The libdlogutil API provides functions for receiving logs programatically.
More...
|
| int | dlogutil_entry_get_tid (const dlogutil_entry_s *entry, pid_t *tid) |
| | Retrieves the TID of the log sender. 6.0.
|
| |
| int | dlogutil_entry_get_pid (const dlogutil_entry_s *entry, pid_t *pid) |
| | Retrieves the PID of the log sender. 6.0.
|
| |
| int | dlogutil_entry_get_tag (const dlogutil_entry_s *entry, const char **tag) |
| | Retrieves the tag of the log entry. 6.0.
|
| |
| int | dlogutil_entry_get_message (const dlogutil_entry_s *entry, const char **msg) |
| | Retrieves the message of the log entry. 6.0.
|
| |
| int | dlogutil_entry_get_timestamp (const dlogutil_entry_s *entry, dlogutil_sorting_order_e order, struct timespec *ts) |
| | Retrieves the timestamp of the log entry. 6.0.
|
| |
| int | dlogutil_entry_get_priority (const dlogutil_entry_s *entry, log_priority *prio) |
| | Retrieves the priority of the log entry. 6.0.
|
| |
| dlogutil_filter_options_s * | dlogutil_filter_options_create (void) |
| | Creates a new dlogutil_filter_options_s struct. 6.0.
|
| |
| void | dlogutil_filter_options_destroy (dlogutil_filter_options_s *filter) |
| | Destroys the dlogutil_filter_options_s struct. 6.0.
|
| |
| int | dlogutil_filter_options_set_tid (dlogutil_filter_options_s *filter, pid_t tid) |
| | Enables retrieving only those logs that are logged by the thread with the given TID. 6.0.
|
| |
| int | dlogutil_filter_options_set_pid (dlogutil_filter_options_s *filter, pid_t pid) |
| | Enables retrieving only those logs that are logged by the process with the given PID. 6.0.
|
| |
| int | dlogutil_filter_options_set_filterspec (dlogutil_filter_options_s *filter, const char *query) |
| | Enables retrieving only those logs that match a given filter. 6.0.
|
| |
| dlogutil_sorting_options_s * | dlogutil_sorting_options_create (void) |
| | Creates a new dlogutil_sorting_options_s struct. 6.0.
|
| |
| void | dlogutil_sorting_options_destroy (dlogutil_sorting_options_s *sorting) |
| | Destroys the dlogutil_sorting_options_s struct. 6.0.
|
| |
| int | dlogutil_sorting_options_disable_sorting (dlogutil_sorting_options_s *sorting) |
| | Disables log sorting. 6.0.
|
| |
| int | dlogutil_sorting_options_enable_sorting (dlogutil_sorting_options_s *sorting) |
| | Enables sorting. 6.0.
|
| |
| int | dlogutil_sorting_options_enable_sorting_with_size (dlogutil_sorting_options_s *sorting, unsigned int entry_count) |
| | Enables sorting, choosing the sort buffer size manually. 6.0.
|
| |
| int | dlogutil_sorting_options_set_sort_by (dlogutil_sorting_options_s *sorting, dlogutil_sorting_order_e sort_by) |
| | Chooses a timestamp type to sort by. 6.0.
|
| |
| int | dlogutil_get_logs_continuous (int buffers, dlogutil_entry_cb callback, void *data, dlogutil_sorting_options_s *sorting, dlogutil_filter_options_s *filter) |
| | Retrieves logs continuously starting from the beginning, until the callback returns a non-zero value. 6.0.
|
| |
| int | dlogutil_get_logs_monitor (int buffers, dlogutil_entry_cb callback, void *data, dlogutil_sorting_options_s *sorting, dlogutil_filter_options_s *filter) |
| | Retrieves logs continuously starting from the function call, until the callback returns a non-zero value. 6.0.
|
| |
| int | dlogutil_get_logs_dump (int buffers, unsigned int entry_count, dlogutil_entry_cb callback, void *data, dlogutil_sorting_options_s *sorting, dlogutil_filter_options_s *filter) |
| | Dumps logs (possibly a specified amount of the most recent of them) and returns. 6.0.
|
| |
| int | dlogutil_buffer_clear (dlogutil_buffer_e buffer) |
| | Clears a log buffer. 6.0.
|
| |
| int | dlogutil_buffer_get_name (dlogutil_buffer_e buffer, const char **name) |
| | Gets the name of a buffer. 6.0.
|
| |
| int | dlogutil_buffer_get_size (dlogutil_buffer_e buffer, unsigned int *size) |
| | Gets the size of a buffer. 6.0.
|
| |
| int | dlogutil_buffer_get_default_ts_type (dlogutil_buffer_e buffer, dlogutil_sorting_order_e *type) |
| | Gets the default timestamp type of a buffer. 6.0.
|
| |
| int | dlogutil_buffer_check_ts_type_available (dlogutil_buffer_e buffer, dlogutil_sorting_order_e type, bool *available) |
| | Checks if a buffer contains timestamps of a given type. 6.0.
|
| |
Required Header
#include <dlogutil.h>
Overview
This API can be used to do everything that the dlogutil CLI can (see dlogutil CLI). The most important use, however, is to receive the logs of the working Tizen system.
Permissions
We require libdlogutil user to either have the CAP_SYSLOG capability, or be in the log group. Otherwise, libdlogutil is unlikely to work correctly (albeit it might in some cases) and using it in such a configuration is unsupported.
Receiving logs
In order to receive logs, you have to use the dlogutil_get_logs_continuous(), dlogutil_get_logs_monitor(), or dlogutil_get_logs_dump() function. In order to call either of those functions, you need to pass a callback (dlogutil_entry_cb). The function will then call this callback repeatedly for every log, quitting in case of a non-zero return value of the callback or in case of an error.
The difference between the three functions is that dlogutil_get_logs_monitor() is meant to monitor the buffer for fresh logs without terminating, dlogutil_get_logs_dump() dumps the current logs and quits, and dlogutil_get_logs_continuous() combines the two - it returns everything in the buffer and waits for more. You can then terminate any of the three functions by returning a non-zero value from the callback, as explained above, and they will return on an error.
The callback will receive a single argument — an instance of the dlogutil_entry_s struct. In the callback you can then use the various functions supplied by the API in order to read the logs data.
One possible issue to be aware of is that reading timestamp data in dlog is nontrivial. In particular, the data might be missing, and the functions will return the special missing value. You can, however, avoid this, by using the dlogutil_get_traits() function. It allows you to receive information about a buffer; in particular, which timestamps are guaranteed to be available, and which timestamp is the default one (which not only is guaranteed to be available, but also is considered by dlog as the best possible representation of the true log sending time).
While receiving logs, you can decide to also sort or filter them. These can be configured by passing custom dlogutil_sorting_options_s and dlogutil_filter_options_s structs.
Timestamp types
The timestamps can be generated by one of the two types of clocks:
- monotonic, which give the time since device boot (which isn't comparable across devices, nor across device boots),
- and realtime, which give the wall-clock time (which isn't sortable, being adjustable backwards by a user).
These map directly to CLOCK_MONOTONIC and CLOCK_REALTIME as described in the clock_getres(2) manpage. Additionally, each timestamp can be either generated by:
- the sender, which means the timestamp is the close representation of the log sending time,
- or the receiver, which means the timestamp tells us when the dlog daemon received the log from the application.
Usually, the sender timestamps are preferable, but they aren't always available.
Sorting quality
When it comes to sorting, there are two options possible:
- sorting may be unnecessary. This might happen when you disable sorting manually, or when you enable sorting by the default timestamp (by which the data is already sorted). In this case, there will be no additional sorting (because it is unnecessary), so the sorting quality will be as good as the log source provides,
- sorting may be necessary, which happens in all other situations. In this case, sorting will be performed.
Unfortunately, sorting the logs in a perfect way is harder than it might look. This is due to the need to output the logs in a timely manner, as well as the sheer amount of them. What if we receive a log from an hour ago? If we have already output the logs from the last second, it is now impossible to output the new log before them. Therefore, correct sorting is impossible in this case. In theory, this issue does not appear in the dump mode, but in this case, the number of logs might become an issue — some products based on Tizen have huge amounts of logs generated every second. In this case, we could end up timing out even if O(nlogn) sorting is used.
Our solution is to compare only close logs, while returning it as they come. The idea is to hold a circular buffer of logs of a fixed size, and, instead of returning incoming logs immediately, put them into the buffer. As we put the log into the buffer, we immediately make sure it's sorted. This is performant in our case because the input is almost sorted (the timestamps of different types should be correlated with each other, and the input is sorted by one of them).
A log will be finally returned in three cases:
- when the buffer is filled up and we receive a new log, the oldest log in the buffer is returned and removed from the buffer to create space for the new one,
- when the oldest log is older than the time limit specified in dlog configuration file, it is returned and removed from the buffer,
- when we receive all logs in the dump mode, the buffer is cleaned up by returning all the remaining logs.
Note that in the first two cases, it is possible, that we will receive in the future a log that should be returned before the returned one. The probability of this happening in the second case depends on the configured time limit, but in general it is extremely low. However, in the first case, missort is possible, and the probability directly depends on the buffer size, which is configurable using the dlogutil_sorting_enable_sorting_with_size() function. The argument will set the size of the sort buffer in entries, which means that the memory usage of the log receiving funtion is mostly linear to this argument (as the buffer will usually stay full most of the time). The default value is currently 131072 and there exists a maximum of 1048576.
We'd like to reiterate that usually you don't need to worry about this, as if you disable sorting or sort by the default timestamp, the data is already received in the correct form, and there isn't even a need to create a buffer, so the data will come sorted as well as the source allows (which usually means perfect sorting).
Other operations
You can also use the API to erase the log buffers — this can be done using the dlogutil_buffer_clear() function.
| #define DLOGUTIL_MAX_DUMP_SIZE UINT_MAX |
- Parameters
-
| [in] | entry | Log entry |
| [in] | data | Callback user data |
- Returns
- If non-zero, no more logs are processed. The return value then becomes dlogutil_get_logs_{continuous,dump} return value
- Precondition
- dlogutil_get_logs_* call this callback.
- See Also
- dlogutil_get_logs_continuous()
-
dlogutil_get_logs_dump()
- Enumerator:
| DLOGUTIL_BUF_MAIN |
Main buffer
|
| DLOGUTIL_BUF_RADIO |
Radio buffer
|
| DLOGUTIL_BUF_SYSTEM |
System buffer
|
| DLOGUTIL_BUF_APPS |
Application buffer
|
| DLOGUTIL_BUF_KMSG |
Kernel message buffer
|
| DLOGUTIL_BUF_SYSLOG |
Syslog buffer
|
- Enumerator:
| DLOGUTIL_SORT_SENT_MONO |
Monotonic timestamp applied by the sender
|
| DLOGUTIL_SORT_SENT_REAL |
Real-time timestamp applied by the sender
|
| DLOGUTIL_SORT_RECV_MONO |
Monotonic timestamp applied by the receiver
|
| DLOGUTIL_SORT_RECV_REAL |
Real-time timestamp applied by the receiver
|
| DLOGUTIL_SORT_DEFAULT |
The default timestamp of the buffer
- See Also
- dlogutil_buffer_get_default_ts_type()
|
- Bug:
- This is currently evaluated using the config file, which can change at runtime. In particular, this can desync from the value of the server if the config file changes. Note that this is mostly a theoretical concern, since the file is not intended to change during the runtime (the daemon asks to reboot the system in such a case).
- Parameters
-
| [in] | buffer | A single buffer to be inspected |
| [in] | type | The timestamp type to be considered |
| [out] | available | Whether the given timestamp type is guaranteed to be available |
- Returns
- An error code
- Return values
-
| TIZEN_ERROR_NONE | Success |
| TIZEN_ERROR_INVALID_PARAMETER | Invalid buffer |
| TIZEN_ERROR_INVALID_PARAMETER | More than one buffer |
| TIZEN_ERROR_INVALID_PARAMETER | The pointer was NULL |
- Parameters
-
| [in] | buffer | A single buffer to be cleared |
- Returns
- An error code
- Return values
-
| TIZEN_ERROR_NONE | Success |
| TIZEN_ERROR_INVALID_PARAMETER | Invalid buffer |
| TIZEN_ERROR_INVALID_PARAMETER | More than one buffer |
| Other | An arbitrary Tizen error code |
- Bug:
- This is currently evaluated using the config file, which can change at runtime. In particular, this can desync from the value of the server if the config file changes. Note that this is mostly a theoretical concern, since the file is not intended to change during the runtime (the daemon asks to reboot the system in such a case).
- Parameters
-
| [in] | buffer | A single buffer to be inspected |
| [out] | type | The default timestamp type of the passed buffer |
- Returns
- An error code
- Return values
-
| TIZEN_ERROR_NONE | Success |
| TIZEN_ERROR_INVALID_PARAMETER | Invalid buffer |
| TIZEN_ERROR_INVALID_PARAMETER | More than one buffer |
| TIZEN_ERROR_INVALID_PARAMETER | The pointer was NULL |
| Other | An arbitrary Tizen error code |
- Parameters
-
| [in] | buffer | A single buffer to be inspected |
| [out] | name | The name of the passed buffer |
- Returns
- An error code
- Return values
-
| TIZEN_ERROR_NONE | Success |
| TIZEN_ERROR_INVALID_PARAMETER | Invalid buffer |
| TIZEN_ERROR_INVALID_PARAMETER | More than one buffer |
| TIZEN_ERROR_INVALID_PARAMETER | The pointer was NULL |
| Other | An arbitrary Tizen error code |
- Bug:
- This is currently evaluated using the config file, which can change at runtime. In particular, this can desync from the value of the server if the config file changes. Note that this is mostly a theoretical concern, since the file is not intended to change during the runtime (the daemon asks to reboot the system in such a case).
- Parameters
-
| [in] | buffer | A single buffer to be inspected |
| [out] | size | The size in entries of the passed buffer |
- Returns
- An error code
- Return values
-
| TIZEN_ERROR_NONE | Success |
| TIZEN_ERROR_INVALID_PARAMETER | Invalid buffer |
| TIZEN_ERROR_INVALID_PARAMETER | More than one buffer |
| TIZEN_ERROR_INVALID_PARAMETER | The pointer was NULL |
| Other | An arbitrary Tizen error code |
| int dlogutil_entry_get_message |
( |
const dlogutil_entry_s * |
entry, |
|
|
const char ** |
msg |
|
) |
| |
- Parameters
-
| [in] | entry | Log entry |
| [out] | msg | Log message |
- Returns
- An error code
- Return values
-
| TIZEN_ERROR_NONE | Success |
| TIZEN_ERROR_INVALID_PARAMETER | One of the pointers was NULL |
| TIZEN_ERROR_NO_DATA | The message is missing |
- Parameters
-
| [in] | entry | Log entry |
| [out] | pid | PID of the log sender |
- Returns
- An error code
- Return values
-
| TIZEN_ERROR_NONE | Success |
| TIZEN_ERROR_INVALID_PARAMETER | One of the pointers was NULL |
| TIZEN_ERROR_NO_DATA | PID missing or not applicable |
- Parameters
-
| [in] | entry | Log entry |
| [out] | prio | Log priority |
- Returns
- An error code
- Return values
-
| TIZEN_ERROR_NONE | Success |
| TIZEN_ERROR_INVALID_PARAMETER | One of the pointers was NULL |
| TIZEN_ERROR_NO_DATA | The priority is missing |
| int dlogutil_entry_get_tag |
( |
const dlogutil_entry_s * |
entry, |
|
|
const char ** |
tag |
|
) |
| |
- Parameters
-
| [in] | entry | Log entry |
| [out] | tag | Log tag |
- Returns
- An error code
- Return values
-
| TIZEN_ERROR_NONE | Success |
| TIZEN_ERROR_INVALID_PARAMETER | One of the pointers was NULL |
| TIZEN_ERROR_NO_DATA | The tag is missing |
- Parameters
-
| [in] | entry | Log entry |
| [out] | tid | TID of the log sender |
- Returns
- An error code
- Return values
-
| TIZEN_ERROR_NONE | Success |
| TIZEN_ERROR_INVALID_PARAMETER | One of the pointers was NULL |
| TIZEN_ERROR_NO_DATA | TID missing or not applicable |
- Parameters
-
| [in] | entry | Log entry |
| [in] | order | Which timestamp to extract. DLOGUTIL_SORT_DEFAULT is NOT allowed currently |
| [out] | ts | Timestamp of the entry |
- Returns
- An error code
- Return values
-
| TIZEN_ERROR_NONE | Success |
| TIZEN_ERROR_INVALID_PARAMETER | Invalid value of order |
| TIZEN_ERROR_INVALID_PARAMETER | One of the pointers was NULL |
| TIZEN_ERROR_NO_DATA | The timestamp is missing |
- See Also
- dlogutil_get_traits()
- Parameters
-
| [in] | filter | A handle to the settings struct. |
| [in] | query | The filter query. For syntax, see dlogutil's –help or dlogutil CLI documentation. |
- Returns
- An error code
- Return values
-
| TIZEN_ERROR_NONE | Success |
| TIZEN_ERROR_INVALID_PARAMETER | Invalid syntax of the filterspec |
| TIZEN_ERROR_INVALID_PARAMETER | One of the pointers was NULL |
| TIZEN_ERROR_OUT_OF_MEMORY | Out of memory |
- Parameters
-
| [in] | filter | A handle to the settings struct. |
| [in] | pid | The PID value. |
- Returns
- An error code
- Return values
-
| TIZEN_ERROR_NONE | Success |
| TIZEN_ERROR_INVALID_PARAMETER | The pointer was NULL |
| TIZEN_ERROR_OUT_OF_MEMORY | Out of memory |
- Parameters
-
| [in] | filter | A handle to the settings struct |
| [in] | tid | The TID value |
- Returns
- An error code
- Return values
-
| TIZEN_ERROR_NONE | Success |
| TIZEN_ERROR_INVALID_PARAMETER | The pointer was NULL |
| TIZEN_ERROR_OUT_OF_MEMORY | Out of memory |
- Parameters
-
| [in] | buffers | A bit field, ORed from values of the dlogutil_buffer_e enum. 0 is equivalent to the default of enabling main, system and apps buffers. Using kmsg or syslog together with other buffers is currently not allowed, but it might become possible in the future |
| [in] | callback | Callback, which will be called for each log (see dlogutil_entry_cb()). Non-zero return value will terminate the function early |
| [in] | data | User data, which will be passed to the callback |
| [in] | sorting | Sorting settings. Can be NULL, in which case we sort on the default timestamp |
| [in] | filter | Filter settings. Can be NULL, in which case we let everything through |
- Returns
- An error code, or the callback return value
- Return values
-
| TIZEN_ERROR_NONE | Should never happen |
| TIZEN_ERROR_INVALID_PARAMETER | Invalid buffer selection |
| TIZEN_ERROR_INVALID_PARAMETER | The callback pointer was NULL |
| Other | Either an arbitrary Tizen error code, or the callback return value |
- See Also
- dlogutil_entry_cb
-
dlogutil_get_logs_dump()
-
dlogutil_get_logs_monitor()
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
{
*(int *)var += 1;
assert(!dlogutil_entry_get_prio(ent, &prio));
}
int main(void)
{
int count = 0;
assert(filter);
assert(sorting);
if (r == 1)
printf("There have been %d error logs before the first fatal log.\n", count - 1);
else
printf("Failure!\n");
}
- Parameters
-
| [in] | buffers | A bit field, ORed from values of the dlogutil_buffer_e enum. 0 is equivalent to the default of enabling main, system and apps buffers. Using kmsg or syslog together with other buffers is currently not allowed, but it might be possible in the future |
| [in] | entry_count | Number of logs to be returned. It can be DLOGUTIL_MAX_DUMP_SIZE, in which case all the logs will be dumped |
| [in] | callback | Callback, which will be called for each log (see dlogutil_entry_cb()). Non-zero return value will terminate the function early |
| [in] | data | User data, which will be passed to the callback Can be NULL, in which case the callback will also receive NULL |
| [in] | sorting | Sorting settings. Can be NULL, in which case we sort on the default timestamp |
| [in] | filter | Filter settings. Can be NULL, in which case we let everything through |
- Returns
- An error code, or the callback return value
- Return values
-
| TIZEN_ERROR_NONE | Success |
| TIZEN_ERROR_INVALID_PARAMETER | Invalid buffer selection |
| TIZEN_ERROR_INVALID_PARAMETER | The callback pointer was NULL |
| Other | Either an arbitrary Tizen error code, or the callback return value |
- See Also
- dlogutil_entry_cb
-
dlogutil_get_logs_continuous()
-
dlogutil_get_logs_monitor()
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
{
*(int *)var += 1;
assert(!dlogutil_entry_get_prio(ent, &prio));
}
int main(void)
{
int count = 0;
assert(filter);
assert(sorting);
if (r == 1)
printf("There have been %d error logs before the first fatal log.\n", count - 1);
else if (r == 0)
printf("There were no fatal logs in first 100 logs analysed.\n");
else
printf("Failure!\n");
}
- Parameters
-
| [in] | buffers | A bit field, ORed from values of the dlogutil_buffer_e enum. 0 is equivalent to the default of enabling main, system and apps buffers. Using kmsg or syslog together with other buffers is currently not allowed, but it might become possible in the future |
| [in] | callback | Callback, which will be called for each log (see dlogutil_entry_cb()). Non-zero return value will terminate the function early |
| [in] | data | User data, which will be passed to the callback |
| [in] | sorting | Sorting settings. Can be NULL, in which case we sort on the default timestamp |
| [in] | filter | Filter settings. Can be NULL, in which case we let everything through |
- Returns
- An error code, or the callback return value
- Return values
-
| TIZEN_ERROR_NONE | Should never happen |
| TIZEN_ERROR_INVALID_PARAMETER | Invalid buffer selection |
| TIZEN_ERROR_INVALID_PARAMETER | The callback pointer was NULL |
| Other | Either an arbitrary Tizen error code, or the callback return value |
- See Also
- dlogutil_entry_cb
-
dlogutil_get_logs_continuous()
-
dlogutil_get_logs_dump()
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
{
*(int *)var += 1;
assert(!dlogutil_entry_get_prio(ent, &prio));
}
int main(void)
{
int count = 0;
assert(filter);
assert(sorting);
if (r == 1)
printf("There have been %d error logs before the first fatal log.\n", count - 1);
else
printf("Failure!\n");
}
- Parameters
-
| [in] | sorting | A handle to the settings struct |
| [in] | sort_by | Which timestamp type to sort by. DLOGUTIL_SORT_DEFAULT is allowed |
- Returns
- An error code
- Return values
-
| TIZEN_ERROR_NONE | Success |
| TIZEN_ERROR_INVALID_PARAMETER | The pointer was NULL |