> For the complete documentation index, see [llms.txt](https://sandbox-docs.verifone.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://sandbox-docs.verifone.com/adk-5.0-programmers-guide/readme/system_overview/pg_all_components/pg_logging_users_guide.md).

# ADK-LOGGING Programmers Guide

## Preface <a href="#sec_logging_preface" id="sec_logging_preface"></a>

This document is intended for developers to understand how to use the ADK logging.

### Audience <a href="#subsec_logging_audience" id="subsec_logging_audience"></a>

This guide provides information of the ADK Logging usage. Discussed topics of application configuration, deployment, API usage. Guide also contains common usage examples.

### Organization <a href="#subsec_logging_organization" id="subsec_logging_organization"></a>

This guide is organized as follows:

[Introduction](#sec_logging_introduction). Brief summary on how ADK Logging works.

[Getting Started](#sec_logging_getting_started). Most simple usage example.

[Programming](#sec_logging_programming). Explains how to use the Logging API.

[System Setup and Requirements](#sec_logging_setup). How to deploy ADK Logging.

[Logging on android devices](#sec_logging_android). Logging on android devices.

[Storage Space, Log Cleanup, and Limits](#sec_logging_cleanup) Storage Space, Log Cleanup, and Limits

[Troubleshooting](#sec_logging_troubleshooting). Common problems encountered for ADK Logging.

[Appendix](#sec_logging_appendix). Known issues and limitations, acronym definition.

## Introduction <a href="#sec_logging_introduction" id="sec_logging_introduction"></a>

This chapter shows the basic logging process used by ADK logging.

### Concepts <a href="#subsec_logging_concepts" id="subsec_logging_concepts"></a>

ADK Logging is a solution targeted to make logging accessible and universal

![ADK Logging](/files/tPnPlzqEDtEJ0EKzFruz)

ADK Logging, uses syslog to process user and system messages.

## Getting Started <a href="#sec_logging_getting_started" id="sec_logging_getting_started"></a>

### ADK Logging Usage Example <a href="#subsec_logging_usage_example" id="subsec_logging_usage_example"></a>

This code below shows most simple example:

```cpp
#include <liblog2.h>
log_hdl = LOGAPI_INIT("demoapp");
LOGF_TRACE(log_hdl, "Trace: %s", "Hello world!");
LOGAPI_DEINIT(log_hdl);
```

First, the header file [liblog2.h](/adk-5.0-programmers-guide/readme/files/dir_f9c8c0699850f5588903704d86bd63e7/dir_9f39dd86019fee8ad514daa97fcb3202/liblog2_8h.md) is included. Next, the logging channel `demoapp` is initialized, and its handle is stored. Tracing is performed using the `LOGF_TRACE()` API function, which utilizes the channel handle and follows printf-style syntax. Once all logging tasks are complete, the channel is closed. In most scenarios, the logging channel should be initialized at application startup and closed at exit, eliminating the need to reopen it before each logging operation. An application can have multiple logging channels, each configured independently. Most parameters are managed through the Logging Control Panel(LCP), that modifies the application's configuration file.

To run this example, you need to create a configuration file for the `demoapp` channel. The file should be named `demoapp_log.conf`. It can be generated using the LCP or included in the application package.

### How To build Example <a href="#subsec_logging_how_to_build_example" id="subsec_logging_how_to_build_example"></a>

You could find ADK Logging example and makefiles in the doc\log\example folder. Follow these steps to build the example:

{% hint style="info" %}
Prerequisites: You have already installed ADK, SDK and toolchain
{% endhint %}

1. Change to *ADK*\doc\log\example folder
2. Edit VERSION.mk file and put your toolchain versions/paths here
3. Build an example:

VOS build:

```cpp
make vos-release-pack
```

VOS2 build:

```cpp
make vos2-release-pack
```

## Programming <a href="#sec_logging_programming" id="sec_logging_programming"></a>

### Configuration <a href="#subsec_new_logging_channel_configuration" id="subsec_new_logging_channel_configuration"></a>

#### Application Channel <a href="#subsubsec_logging_configuration_application_channel" id="subsubsec_logging_configuration_application_channel"></a>

Each logging channel used in the application must be configured; otherwise, logging will be disabled for that channel.

ADK Logging relies on a JSON-format configuration file that stores all logging parameters, such as masks, verbosity, and more. This file is managed through the LCP or Logging API: [Configuration functions](#subsubsec_new_application_configuration_functions) Configuration file for the example above: demoapp\_log.conf.

```cpp
{
  "schema_version": "1.0",
  "enabled": true,
  "mask": 16,
  "verbosity" : 1,
  "output" : "LOGAPI_SYSLOG"
}
```

#### Log Masks <a href="#subsubsec_new_application_configuration_log_masks" id="subsubsec_new_application_configuration_log_masks"></a>

| Log level      | Bitmask | Log level description             |
| -------------- | ------- | --------------------------------- |
| LOGAPI\_EMERG  | 1       | Emergency / system is unusable    |
| LOGAPI\_ALERT  | 2       | An immediate action must be taken |
| LOGAPI\_CRIT   | 4       | Critical conditions               |
| LOGAPI\_ERROR  | 8       | Error reporting                   |
| LOGAPI\_WARN   | 16      | Warning reporting                 |
| LOGAPI\_NOTICE | 32      | Normal, but significant condition |
| LOGAPI\_INFO   | 64      | Regular info message              |
| LOGAPI\_TRACE  | 128     | High verbosity messages           |

#### Verbosity <a href="#subsubsec_new_application_configuration_verbosity" id="subsubsec_new_application_configuration_verbosity"></a>

Following information is available with verbosity mode switched "ON":

* FILE:LINE
* \[PROCESS ID]
* \[THREAD ID]

#### Output sources <a href="#subsubsec_new_application_configuration_output_sources" id="subsubsec_new_application_configuration_output_sources"></a>

| Output          | Description                       |
| --------------- | --------------------------------- |
| LOGAPI\_CONSOLE | Output to console                 |
| LOGAPI\_SYSLOG  | Output to syslog                  |
| LOGAPI\_ALL     | Output to both console and syslog |

#### ADK Component Configuration <a href="#subsubsec_new_logging_adk_configuration" id="subsubsec_new_logging_adk_configuration"></a>

Each ADK component initializes its channel using a stored configuration file. The file is named in the format **`id_log.conf`**`,` where `id` represents the ADK component `ID`. For example, the configuration file for the `ADK` **`COM`**` ``channel` is named **`COM_log.conf`**`.`

The table below lists all ADK components and their corresponding IDs:

| Component name                        | Component Id | [Config](/adk-5.0-programmers-guide/readme/annotated/class_config.md) bundle VOS                                                   |
| ------------------------------------- | ------------ | ---------------------------------------------------------------------------------------------------------------------------------- |
| ADK-ASL (ADK system loader)           | ASL          | [dl.ASL\_log\_cfg.tgz](https://github.com/verifoneone/verifone-git-book-adk/tree/ADK5.0_staging/config/dl.ASL_log_cfg.tgz)         |
| ADK-AST (Anti Skimming Tool)          | AST          | [dl.AST\_log\_cfg.tgz](https://github.com/verifoneone/verifone-git-book-adk/tree/ADK5.0_staging/config/dl.AST_log_cfg.tgz)         |
| ADK-CCP (Communication Control Panel) | CCP          | [dl.CCP\_log\_cfg.tgz](https://github.com/verifoneone/verifone-git-book-adk/tree/ADK5.0_staging/config/dl.CCP_log_cfg.tgz)         |
| ADK-COM (Communication Service)       | COM          | [dl.COM\_log\_cfg.tgz](https://github.com/verifoneone/verifone-git-book-adk/tree/ADK5.0_staging/config/dl.COM_log_cfg.tgz)         |
| ADK-CP (Commerce platform)            | CPR          | [dl.CPR\_log\_cfg.tgz](https://github.com/verifoneone/verifone-git-book-adk/tree/ADK5.0_staging/config/dl.CPR_log_cfg.tgz)         |
| ADK-CPL (Commerce Platform Library)   | CPL          | [dl.CPL\_log\_cfg.tgz](https://github.com/verifoneone/verifone-git-book-adk/tree/ADK5.0_staging/config/dl.CPL_log_cfg.tgz)         |
| ADK-EMV-CT (EMV Contact)              | EMVCT        | [dl.EMVCT\_log\_cfg.tgz](https://github.com/verifoneone/verifone-git-book-adk/tree/ADK5.0_staging/config/dl.EMVCT_log_cfg.tgz)     |
| ADK-EMV-CTLS (EMV Contactless)        | EMVCTLS      | [dl.EMVCTLS\_log\_cfg.tgz](https://github.com/verifoneone/verifone-git-book-adk/tree/ADK5.0_staging/config/dl.EMVCTLS_log_cfg.tgz) |
| ADK-EVENT                             | EVT          | [dl.EVT\_log\_cfg.tgz](https://github.com/verifoneone/verifone-git-book-adk/tree/ADK5.0_staging/config/dl.EVT_log_cfg.tgz)         |
| ADK-FPS (Finger print sensor)         | FPS          | [dl.FPS\_log\_cfg.tgz](https://github.com/verifoneone/verifone-git-book-adk/tree/ADK5.0_staging/config/dl.FPS_log_cfg.tgz)         |
| ADK-UTIL-EXPAT                        | EXP          | [dl.EXP\_log\_cfg.tgz](https://github.com/verifoneone/verifone-git-book-adk/tree/ADK5.0_staging/config/dl.EXP_log_cfg.tgz)         |
| ADK-PRX                               | PRX          | [dl.PRX\_log\_cfg.tgz](https://github.com/verifoneone/verifone-git-book-adk/tree/ADK5.0_staging/config/dl.PRX_log_cfg.tgz)         |
| ADK-INF                               | INF          | [dl.INF\_log\_cfg.tgz](https://github.com/verifoneone/verifone-git-book-adk/tree/ADK5.0_staging/config/dl.INF_log_cfg.tgz)         |
| ADK-IPC (IPC layer)                   | IPC          | [dl.IPC\_log\_cfg.tgz](https://github.com/verifoneone/verifone-git-book-adk/tree/ADK5.0_staging/config/dl.IPC_log_cfg.tgz)         |
| ADK-IPC (Notification server)         | NFY          | [dl.NFY\_log\_cfg.tgz](https://github.com/verifoneone/verifone-git-book-adk/tree/ADK5.0_staging/config/dl.NFY_log_cfg.tgz)         |
| ADK-IPC (Notification clients)        | NFYCL        | [dl.NFYCL\_log\_cfg.tgz](https://github.com/verifoneone/verifone-git-book-adk/tree/ADK5.0_staging/config/dl.NFYCL_log_cfg.tgz)     |
| ADK-GUIPRT (GUI server)               | GUI          | [dl.GUI\_log\_cfg.tgz](https://github.com/verifoneone/verifone-git-book-adk/tree/ADK5.0_staging/config/dl.GUI_log_cfg.tgz)         |
| ADK-GUIPRT (GUI clients)              | GUICL        | [dl.GUICL\_log\_cfg.tgz](https://github.com/verifoneone/verifone-git-book-adk/tree/ADK5.0_staging/config/dl.GUICL_log_cfg.tgz)     |
| ADK-GUIPRT (Printer server)           | PRT          | [dl.PRT\_log\_cfg.tgz](https://github.com/verifoneone/verifone-git-book-adk/tree/ADK5.0_staging/config/dl.PRT_log_cfg.tgz)         |
| ADK-GUIPRT (Printer clients)          | PRTCL        | [dl.PRTCL\_log\_cfg.tgz](https://github.com/verifoneone/verifone-git-book-adk/tree/ADK5.0_staging/config/dl.PRTCL_log_cfg.tgz)     |
| ADK-MSR                               | MSR          | [dl.MSR\_log\_cfg.tgz](https://github.com/verifoneone/verifone-git-book-adk/tree/ADK5.0_staging/config/dl.MSR_log_cfg.tgz)         |
| ADK-NFC (NFC framework)               | NFC          | [dl.NFC\_log\_cfg.tgz](https://github.com/verifoneone/verifone-git-book-adk/tree/ADK5.0_staging/config/dl.NFC_log_cfg.tgz)         |
| ADK-SDI                               | SDI          | [dl.SDI\_log\_cfg.tgz](https://github.com/verifoneone/verifone-git-book-adk/tree/ADK5.0_staging/config/dl.SDI_log_cfg.tgz)         |
| ADK-SEC                               | SEC          | [dl.SEC\_log\_cfg.tgz](https://github.com/verifoneone/verifone-git-book-adk/tree/ADK5.0_staging/config/dl.SEC_log_cfg.tgz)         |
| ADK-SYS (client)                      | SYSCL        | [dl.SYSCL\_log\_cfg.tgz](https://github.com/verifoneone/verifone-git-book-adk/tree/ADK5.0_staging/config/dl.SYSCL_log_cfg.tgz)     |
| ADK-SYS (server)                      | SYS          | [dl.SYS\_log\_cfg.tgz](https://github.com/verifoneone/verifone-git-book-adk/tree/ADK5.0_staging/config/dl.SYS_log_cfg.tgz)         |
| ADK-TEC                               | TEC          | [dl.TEC\_log\_cfg.tgz](https://github.com/verifoneone/verifone-git-book-adk/tree/ADK5.0_staging/config/dl.TEC_log_cfg.tgz)         |
| ADK-TMS-AGENT                         | TMS          | [dl.TMS\_log\_cfg.tgz](https://github.com/verifoneone/verifone-git-book-adk/tree/ADK5.0_staging/config/dl.TMS_log_cfg.tgz)         |
| ADK-PM (Power managment)              | PM           | [dl.PM\_log\_cfg.tgz](https://github.com/verifoneone/verifone-git-book-adk/tree/ADK5.0_staging/config/dl.PM_log_cfg.tgz)           |
| ADK-PM (Power managment clients)      | PMCL         | [dl.PMCL\_log\_cfg.tgz](https://github.com/verifoneone/verifone-git-book-adk/tree/ADK5.0_staging/config/dl.PMCL_log_cfg.tgz)       |
| ADK-MAC (MAC)                         | MAC          | [dl.MAC\_log\_cfg.tgz](https://github.com/verifoneone/verifone-git-book-adk/tree/ADK5.0_staging/config/dl.MAC_log_cfg.tgz)         |
| ADK-MAC (MACt clients)                | MACCL        | [dl.MACCL\_log\_cfg.tgz](https://github.com/verifoneone/verifone-git-book-adk/tree/ADK5.0_staging/config/dl.MACCL_log_cfg.tgz)     |
| ADK-LCP                               | LCP          | [dl.LCP\_log\_cfg.tgz](https://github.com/verifoneone/verifone-git-book-adk/tree/ADK5.0_staging/config/dl.LCP_log_cfg.tgz)         |

{% hint style="info" %}
VOS2 only: The following non-ADK channels can also be configured using LCP: VOSBT, VOSGSM, VOSNET, VOSWIFI
{% endhint %}

Package to disable all ADK logging V/OS: [dl.disable\_logs.tgz](https://github.com/verifoneone/verifone-git-book-adk/tree/ADK5.0_staging/config/dl.disable_logs.tgz)

#### Configuration Package <a href="#subsubsec_new_application_configuration_package" id="subsubsec_new_application_configuration_package"></a>

For the **VOS** platform, configuration file should be placed to the "/mnt/flash/etc/config/adk-log" directory. This can be reached if package has "Type: flashconfig" in "control" file and destination file starts with "adk-log/" prefix. In this case config package content is extracted to the directory "/mnt/flash/etc/config/adk-log". For backward compatibility configuration file for requested channel is also searched in "/mnt/flash/etc/config/" directory if nothing is found in "/mnt/flash/etc/config/adk-log" directory. But note, LCP completely ignores content located in obsolete "/mnt/flash/etc/config/" directory.

In the **VOS3** platform configuration files stored at "/mnt/appdata/versioned/globalshare/adk-log/" directory. You can enable ADK Component logging by installing the log enable package. Packages are stored: In ADK *full* release package: "doc/log/example/load/config/vos3" In ADK-Log *full* release package "vos3/load/log/config" Among of all logging enable packages for ADK Components, that are system signed, there is a *SAMPLE* package that is signed as usr1. This is example how to create user-made logging enable packages.

#### Configuration functions <a href="#subsubsec_new_application_configuration_functions" id="subsubsec_new_application_configuration_functions"></a>

The following API is used to modify configuration options for any LOG channel:

| Function                                   | Description                                                                                     |
| ------------------------------------------ | ----------------------------------------------------------------------------------------------- |
| `LOGAPI_GETCONFIG(channel, param, *value)` | Retrieves the configuration parameter for the specified channel and stores its value in *value* |
| `LOGAPI_SETCONFIG(channel, param, value)`  | Sets the specified channel configuration parameter to the value provided in *value*             |

{% hint style="info" %}
After channel configuration done you may need to call LOGAPI\_RECONFIG\_NOTIFY() to make all channels re-read their configuration files
{% endhint %}

| Parameter                | Description                                                                                                             |
| ------------------------ | ----------------------------------------------------------------------------------------------------------------------- |
| LOGAPI\_ENABLED\_PARAM   | `enabled` parameter. As value you must specify LOGAPI\_ENABLED or LOGAPI\_DISABLED                                      |
| LOGAPI\_MASK\_PARAM      | `mask` parameter (See [Log Masks](#subsubsec_new_application_configuration_log_masks) for available values)             |
| LOGAPI\_VERBOSITY\_PARAM | `verbosity` parameter (See [Verbosity](#subsubsec_new_application_configuration_verbosity) for available values)        |
| LOGAPI\_OUTPUT\_PARAM    | `output` parameter (see [Output sources](#subsubsec_new_application_configuration_output_sources) for available values) |

Configuration functions could return following error codes:

| Code                 | Description                                      |
| -------------------- | ------------------------------------------------ |
| LOGAPI\_CFG\_OK      | Configuration done                               |
| LOGAPI\_PARAM\_ERROR | Parameter is not supported                       |
| LOGAPI\_VALUE\_ERROR | Value out of range                               |
| LOGAPI\_READ\_ERROR  | Error parsing channel current configuration file |
| LOGAPI\_WRITE\_ERROR | Error writing configuration file                 |

### Initialization Functions <a href="#subsec_logging_init_api" id="subsec_logging_init_api"></a>

Before an application can log any data, it must initialize the logging channel(s). Once all logging is complete (typically at exit), the application should close these channels. The following API functions handle these tasks:

| Function                | Description                                           |
| ----------------------- | ----------------------------------------------------- |
| `LOGAPI_INIT(channel)`  | Initializes `liblog` channel. Returns channel handle. |
| `LOGAPI_DEINIT(handle)` | Deinitializes liblog channel.                         |

### Logging Functions <a href="#subsec_logging_logging_api" id="subsec_logging_logging_api"></a>

Generic logging functions are level-specific. All these functions take *handle* from LOGAPI\_INIT() and use printf-like *format*. Provided function set from less critical level *TRACE* till most critical level *EMERG*.

| Function                           | Description               |
| ---------------------------------- | ------------------------- |
| `LOGF_TRACE(handle, format, ...)`  | Log *Trace* message       |
| `LOGF_INFO(handle, format, ...)`   | Log *Information* message |
| `LOGF_NOTICE(handle, format, ...)` | Log *Notice* message      |
| `LOGF_WARN(handle, format, ...)`   | Log *Warning* message     |
| `LOGF_ERROR(handle, format, ...)`  | Log *Error* message       |
| `LOGF_CRIT(handle, format, ...)`   | Log *Critical* message    |
| `LOGF_ALERT(handle, format, ...)`  | Log *Alert* message       |
| `LOGF_EMERG(handle, format, ...)`  | Log *Emergency* message   |

You must pass a valid *handle*. Passing deinitialized handle results in undefined behavior.

**Example**

```cpp
LOGF_TRACE(handle, "Trace Printf %d test", 1);
```

Result:

```cpp
<71>Sep 17 10:28:41 TESTD: (src/main.cpp:117) Trace Printf 1 test
```

In the **VOS3** platform there are additional auxiliary functions:

| Function              | Description                                                                                                                                                                                   |
| --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `LOGF_ESCAPE(string)` | Processes a string by removing non-printable characters. Returns a pointer to a new string escaped string. Memory for the new string is obtained with new(), and must be freed with delete(). |

### Hex Dump Logging Functions <a href="#subsec_logging_hex_dump_api" id="subsec_logging_hex_dump_api"></a>

Hex Dump Logging Functions like a generic logging functions are level-specific, so functions available for each Log Level. There are two choices are available for Hex Dump format output: *RAW* and *FULL*.

**Raw Hex Dump** Raw Hex Dump API generates output messages in traditional format: Offset + HEX + ASCII. Example:

```cpp
char buffer[15] = “logapi hexdump”;
LOGAPI_HEXDUMP_RAW_TRACE(handle, (void *)buffer, 15);
```

The result is:

```cpp
6C 6F 67 61 70 69 20 68 65 78 64 75 6D 70 00 logapi hexdump
```

**Full Hex Dump** Full Hex Dump API additionally adds separator line, title, data and size information. Example:

```cpp
const char buf[] = "12345678901234567890123456789012345678901234567890\x00\x01\xFF";
LOGAPI_HEXDUMP_TRACE( handle, "Buffer", buf, sizeof( buf ) );
```

The result is:

```cpp
<71>Sep 17 10:28:41 TESTD: Buffer ptr:0x7041FB7C size:0x36
<71>Sep 17 10:28:41 TESTD: ---- ----------------------------------------------- ----------------
<71>Sep 17 10:28:41 TESTD: 000| 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 1234567890123456
<71>Sep 17 10:28:41 TESTD: 010| 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 7890123456789012
<71>Sep 17 10:28:41 TESTD: 020| 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 3456789012345678
<71>Sep 17 10:28:41 TESTD: 030| 39 30 00 01 FF 00 90....
<71>Sep 17 10:28:41 TESTD: ---- ----------------------------------------------- ----------------
```

Raw Hex Dump functions:

| Function                                        | Description                    |
| ----------------------------------------------- | ------------------------------ |
| `DBG_HEXDUMP_TRACE(handle, data, size)`         | Debug hex dump message         |
| `LOGAPI_HEXDUMP_RAW_TRACE(handle, data, size)`  | Hex dump *Trace* message       |
| `LOGAPI_HEXDUMP_RAW_INFO(handle, data, size)`   | Hex dump *Information* message |
| `LOGAPI_HEXDUMP_RAW_NOTICE(handle, data, size)` | Hex dump *Notice* message      |
| `LOGAPI_HEXDUMP_RAW_WARN(handle, data, size)`   | Hex dump *Warning* message     |
| `LOGAPI_HEXDUMP_RAW_ERROR(handle, data, size)`  | Hex dump *Error* message       |
| `LOGAPI_HEXDUMP_RAW_CRIT(handle, data, size)`   | Hex dump *Critical* message    |
| `LOGAPI_HEXDUMP_RAW_ALERT(handle, data, size)`  | Hex dump *Alert* message       |
| `LOGAPI_HEXDUMP_RAW_EMERG(handle, data, size)`  | Hex dump *Emergency* message   |

Full Hex Dump functions:

| Function                                           | Description                    |
| -------------------------------------------------- | ------------------------------ |
| `DBG_HEXDUMP_TRACE(handle, title, data, size)`     | Debug hex dump message         |
| `LOGAPI_HEXDUMP_TRACE(handle, title, data, size)`  | Hex dump *Trace* message       |
| `LOGAPI_HEXDUMP_INFO(handle, title, data, size)`   | Hex dump *Information* message |
| `LOGAPI_HEXDUMP_NOTICE(handle, title, data, size)` | Hex dump *Notice* message      |
| `LOGAPI_HEXDUMP_WARN(handle, title, data, size)`   | Hex dump *Warning* message     |
| `LOGAPI_HEXDUMP_ERROR(handle, title, data, size)`  | Hex dump *Error* message       |
| `LOGAPI_HEXDUMP_CRIT(handle, title, data, size)`   | Hex dump *Critical* message    |
| `LOGAPI_HEXDUMP_ALERT(handle, title, data, size)`  | Hex dump *Alert* message       |
| `LOGAPI_HEXDUMP_EMERG(handle, title, data, size)`  | Hex dump *Emergency* message   |

Parameter *title* shall specify the string which should be printed in the header of the hexdump output. If the parameter value is NULL, then the header will contain 0 in place of the title Parameter *data* shall contain the pointer to the data, which is required to be printed. The parameter expects `void` \* `pointer`. `Parameter` *size* indicates the length of the data in bytes.

It should be always kept in mind, that the data printed will be a set of bytes stored in the specified address passed in this parameter. If the parameter value is NULL, then nothing will be printed

{% hint style="info" %}
A misleading situation may occur, when the intention is to print a hex representation of the `const` `char` \* string, but the pointer to an `std::string` object is passed instead. In such case, the hexdump will print the contents of the `std::string` object, which is not originally expected.
{% endhint %}

### Syslog Daemon Configuration API <a href="#subsec_logging_api_for_controlling_a_syslog_daemon" id="subsec_logging_api_for_controlling_a_syslog_daemon"></a>

Syslog daemon could be configured by API calls:

| Macro                                                                                                                                                                                                                                        | Description                                                 |
| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------- |
| [syslcmd\_set\_level(enum SYSL\_LVL lvl)](/adk-5.0-programmers-guide/readme/files/dir_f9c8c0699850f5588903704d86bd63e7/dir_9f39dd86019fee8ad514daa97fcb3202/syslogcmd_8h.md#a9b45919ef5fe9f2b4ec89ff27d19ec30)                               | Sets maximum logging level                                  |
| [syslcmd\_set\_source(enum SYSL\_SRC src)](/adk-5.0-programmers-guide/readme/files/dir_f9c8c0699850f5588903704d86bd63e7/dir_9f39dd86019fee8ad514daa97fcb3202/syslogcmd_8h.md#afa7176aab63ea25440d5790c64885caa)                              | Sets a source of log messages Note: has no effect on V/OS   |
| [syslcmd\_set\_dest\_COM(int serial\_port)](/adk-5.0-programmers-guide/readme/files/dir_f9c8c0699850f5588903704d86bd63e7/dir_9f39dd86019fee8ad514daa97fcb3202/syslogcmd_8h.md#a155d47993134d2694a06ffd000d06dd8)                             | Sets destination to COM                                     |
| [syslcmd\_set\_dest\_UDP(const char \*addr, int port)](/adk-5.0-programmers-guide/readme/files/dir_f9c8c0699850f5588903704d86bd63e7/dir_9f39dd86019fee8ad514daa97fcb3202/syslogcmd_8h.md#ae5d5ce27ee87e076c762b06d8fe26fc5)                  | Sets destination to UDP                                     |
| [syslcmd\_set\_dest\_FILE(const char \*filename)](/adk-5.0-programmers-guide/readme/files/dir_f9c8c0699850f5588903704d86bd63e7/dir_9f39dd86019fee8ad514daa97fcb3202/syslogcmd_8h.md#aff55c12911bcfc4dceee1e717a904e88)                       | Sets destination to file                                    |
| [syslcmd\_set\_cfg\_int(enum config\_option option, int ival)](/adk-5.0-programmers-guide/readme/files/dir_f9c8c0699850f5588903704d86bd63e7/dir_9f39dd86019fee8ad514daa97fcb3202/syslogcmd_8h.md#a8fe51a2185b092cbdcd6e883b93248bf)          | Sets integer options(others than UDP host and file name)    |
| [syslcmd\_set\_cfg\_str(enum config\_option option, const char \*sval)](/adk-5.0-programmers-guide/readme/files/dir_f9c8c0699850f5588903704d86bd63e7/dir_9f39dd86019fee8ad514daa97fcb3202/syslogcmd_8h.md#aa4b80452347490e05b502546792aadae) | Sets string options(UDP host and file name)                 |
| [syslcmd\_get\_cfg\_int(enum config\_option option, int \*ival)](/adk-5.0-programmers-guide/readme/files/dir_f9c8c0699850f5588903704d86bd63e7/dir_9f39dd86019fee8ad514daa97fcb3202/syslogcmd_8h.md#a1665cdbed014c0926a02a242708c5234)        | Returns integer options(others than UDP host and file name) |
| [syslcmd\_get\_cfg\_str(enum config\_option option, char \*sval)](/adk-5.0-programmers-guide/readme/files/dir_f9c8c0699850f5588903704d86bd63e7/dir_9f39dd86019fee8ad514daa97fcb3202/syslogcmd_8h.md#a94f13c3a6a608ba2c24ace72bbc2714c)       | Returns string options(UDP host and file name)              |
| [syslcmd\_apply\_config()](/adk-5.0-programmers-guide/readme/files/dir_f9c8c0699850f5588903704d86bd63e7/dir_9f39dd86019fee8ad514daa97fcb3202/syslogcmd_8h.md#ae79e868aa5c9cd5cbcf2772c9938c8ce)                                              | Apply configuration to syslog daemon                        |

Example:

```cpp
#include <syslogcmd.h>
syslcmd_get_cfg_int(ENABLED, enabled);
syslcmd_apply_config();
```

The following configuration options are available:

| Configuration option | Description                              |
| -------------------- | ---------------------------------------- |
| `ENABLED`            | Enable/Disable syslog daemon             |
| `DESTINATION`        | Destination (Serial, UDP, File, USB)     |
| `SERIAL_COM`         | COM port, if destination is serial       |
| `UDP_HOST`           | UDP host, if destination UDP             |
| `UDP_PORT`           | UDP host port, if destination UDP        |
| `LOG_LEVEL`          | Log message level                        |
| `FILE_NAME`          | File name, if destination File           |
| `MAX_LOGFILE_SIZE`   | Max log file size, if destination File   |
| `NUMBER_OF_FILES`    | Number of log files, if destination File |
| `LOG_FORMAT`         | Log format (RFC3164 or RFC5424)          |

### Logging control panel <a href="#subsec_lcp" id="subsec_lcp"></a>

#### ADK logging configuration <a href="#sec_conf_v2" id="sec_conf_v2"></a>

![](/files/GOhq5yPh1HVa06BB7PZ7)

#### LCP Main Screen <a href="#sec_lcp_overview_main_screen" id="sec_lcp_overview_main_screen"></a>

The Logging Control Panel (LCP) is a tool to provide the user of an ADK based Verifone Payment device with the following functions:

1. Set / change the application logging settings
2. Set / change the syslog settings
3. Set / change logs destination
4. Check versions of LCP, liblog, syslog

The following picture shows the main screen of the LCP :

| Screenshot                       | Hints                                                                                                                                                                                                                                                                                                                                      |
| -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| ![](/files/NMqS7JdAUZdzHpaRna5P) | <p>This is main menu, to configure ADK logging:<br><br>Application - configuration for single application<br>Syslog - configuration for global syslog<br>Destination - configuration where to send/store logs<br>Transfer Logs - Transfers syslog logs to external drive<br>Version - information about LCP, Liblog and Syslog version</p> |

#### LCP application menu <a href="#sec_lcp_application_menu" id="sec_lcp_application_menu"></a>

| Screenshot                       | Hints                                                                                                                                                                                                                                                                                                          |
| -------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ![](/files/4Pbj0WD2wrn2nwuJRzCK) | <p>This is application configuraton menu:<br><br>Create config - create new logging configuration for application<br>Edit config - edit already existing application logging configuration<br>Remove config - remove existing application configuration<br>Apply config - applys new/changed configuration</p> |

| Screenshot                       | Hints                                                                                                                                                 |
| -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| ![](/files/670Z3lpv3vb2oL4PyQ8D) | <p>Application configuration:<br><br>APPID - same as used in LOGAPI\_INIT(APPID)<br>Enabled - enable/disable logs from application<br>Verbosity -</p> |
| ![](/files/fEQdJhqZn9LfbljAFpgJ) | <p>Application configuration:<br><br>Log mask - Can set which logs to see from application</p>                                                        |

| Screenshot                       | Hints                                                                                |
| -------------------------------- | ------------------------------------------------------------------------------------ |
| ![](/files/luMIPqBjpagRAh65KNpQ) | When editing/removing application configuration list of all configurations is showed |

#### LCP syslog settings <a href="#sec_lcp_syslog_menu" id="sec_lcp_syslog_menu"></a>

| Screenshot                       | Hints                                                                                                                                                                                                                                                                                       |
| -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ![](/files/2WmxBoVJf0CaPCrprfc9) | <p>Syslog configuration:<br><br>Destination - where to send/store logs (more options under Main menu -> Destinations<br>Log level - max level of log message. See <a href="#subsubsec_new_application_configuration_log_masks">Log masks</a> for detailed description of each log level</p> |
| ![](/files/rLUSUBfsznyU9dzTXRxm) | <p>Syslog configuration:<br><br>Log format - syslog daemon will compose messages according to chosen format</p>                                                                                                                                                                             |

#### LCP destination menu <a href="#sec_lcp_destination_menu" id="sec_lcp_destination_menu"></a>

| Screenshot                       | Hints                                                                                |
| -------------------------------- | ------------------------------------------------------------------------------------ |
| ![](/files/3C9DuMPkVrn41xVJZSIx) | <p>Destination menu:<br><br>File settings<br>Serial settings<br>UDP settings<br></p> |

| Screenshot                       | Hints                                                                                                                                                                                                                                                                                                                                                                                             |
| -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ![](/files/x4BEsPCmsVTXnCqTzfN2) | <p>File settings:<br><br>File name - name of file where to write logs<br>Number of files - how many files keep for log rotation. Range: 1..99<br>Max file size (in Kb) - max size of each file. Range: 1..4096<br><br><strong>Notice:</strong><br>Device flash section is with size of 12MB (compression is used).<br><br>This limits to aprox. 40 MB of uncompressed syslog messages as max.</p> |

| Screenshot                       | Hints                                                                                   |
| -------------------------------- | --------------------------------------------------------------------------------------- |
| ![](/files/aw8pssySj8iUZcpRfGKJ) | <p>Serial settings:<br><br>Port number - number of pourt where to send log messages</p> |

| Screenshot                       | Hints                                                                                                          |
| -------------------------------- | -------------------------------------------------------------------------------------------------------------- |
| ![](/files/kbM4fRbuzpQkLxptKGDw) | <p>UDP settings:<br><br>IP - IP where to send log messages<br>Port - port of IP where to send log messages</p> |

#### LCP version info <a href="#sec_lcp_version_info" id="sec_lcp_version_info"></a>

| Screenshot                       | Hints                                                                                                                            |
| -------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| ![](/files/0Xy1EInFOVZAwQyENwrc) | <p>Versions:<br><br>lcp version - LCP version<br>liblog version - liblog version used<br>syslog version - version of syslogc</p> |

### Miscellaneous API <a href="#subsec_logging_miscellaneous_api" id="subsec_logging_miscellaneous_api"></a>

Listed below are the miscellaneous APIs used for logging

| Macro                           | Description                                                                                                                                                           |
| ------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `LOGAPI_RECONFIG_NOTIFY()`      | Notifies all applications and channels to re-read their configuration files.                                                                                          |
| `LOGAPI_DUMP_SYS_INFO`          | Outputs essential system info such as OS version, RAM size, model number and so on.                                                                                   |
| `log_getVersion()`              | Returns string with version of a library                                                                                                                              |
| `Log_GetSvcVersion()`           | Returns string with version of a syslog daemon                                                                                                                        |
| `LOGAPI_PRINT_CALLSTACK(level)` | <p>Prints actual call stack.</p><div data-gb-custom-block data-tag="hint" data-style="info" class="hint hint-info"><p>Note</p><p>Implemented only for V/OS.</p></div> |
| `dumpLogs(location, fileName)`  | Dumps logs to /tmp/ folder (0) or to external storage (1) . File name "logs" will create file "logs.tgz"                                                              |

## System Setup and Requirements <a href="#sec_logging_setup" id="sec_logging_setup"></a>

### Deploy liblog <a href="#subsec_logging_deployment_liblog" id="subsec_logging_deployment_liblog"></a>

liblog ships in two forms -- as a shared object (`liblog.so`) and a static library (`liblog-static.a`).

To use liblog on V/OS, one must link against libsvc\_logmgr.so (located under **SDK\_DIR%/usr/local/lib**).

{% hint style="info" %}
In order for linker to resolve symbols in a correct manner, path to said libraries has to be put after a path to `liblog-static.a`.
{% endhint %}

There is also a [syslogcmd.h](/adk-5.0-programmers-guide/readme/files/dir_f9c8c0699850f5588903704d86bd63e7/dir_9f39dd86019fee8ad514daa97fcb3202/syslogcmd_8h.md) with API for controlling syslog daemon.

### VOS logging service <a href="#subsec_logging_deployment_syslogd_vos" id="subsec_logging_deployment_syslogd_vos"></a>

Terminal already has default syslog configuration file `user_syslog.conf`. VOS1/VOS2 - `/mnt/flash/etc/config/syslog/user_syslog`.conf. VOS3 - `/mnt/appdata/versioned/globalshare/syslog/user_syslog`.conf.

`Default` `user_syslog.conf` content:

* enabled = 1
* log\_level = 6
* number\_of\_files = 2
* max\_logfile\_size = 200
* destination = 2
* file\_name = messages
* udp\_host = 127.0.0.1
* udp\_port = 514
* serial\_com = 1
* log\_format = 0

{% hint style="info" %}
This file could be modified through syslcmd\_set\_XXX calls. Please refer to subsubsec\_logging\_configuration.
{% endhint %}

### Syslog Configuration File <a href="#sec_logging_syslog_configuration_file" id="sec_logging_syslog_configuration_file"></a>

This section gives an overview of parameters which can be set for syslog daemon (see **example/conf/syslog.conf** for example).

`enabled` -- \[1 -- enabled, 0 - disabled] enables or disables syslog daemon

`destination` -- sets destination for log messages.

* 0 -- serial
* 1 -- UDP
* 2 -- File (default)
* 3 -- USB \[\*]

{% hint style="info" %}
\[\*] - USB port should be in device mode and connected to PC. Logging through serial over USB is only supported mode.
{% endhint %}

`log_level` -- sets maximum level of a log message:

* 0 -- LOG\_EMERG
* 1 -- LOG\_ALERT
* 2 -- LOG\_CRIT
* 3 -- LOG\_ERR
* 4 -- LOG\_WARNING
* 5 -- LOG\_NOTICE
* 6 -- LOG\_INFO
* 7 -- LOG\_DEBUG

`file_name` -- denotes the name of the output file when a file is specified as the destination

There are two log files:

* Temporary memory: /var/log/messages -- Contains logs from the most recent reboot.
* Permanent memory (flash): VOS1/VOS2 - /mnt/flash/logs/system/messages. VOS3 - /mnt/sysdata/logs/messages for the system messages and /mnt/appdata/logs/messages for the user/application messages.

The `file_name` configuration parameter specifies the file name in temporary memory (VOS1/VOS2).

{% hint style="info" %}
VOS3 does not use this; instead, it consistently uses the name 'messages'.
{% endhint %}

`max_logfile_size` -- maximum log file size (in Kb) before logs get rotated

`number_of_files` -- number of files to rotate, i.e `<file_name>0` would contain the most recent logs and `<file_name>9` would contain the oldest.

`send_retries` -- count of retries to be attempted by daemon to resend failed message

`serial_com` -- \[1,2,6] when serial is set as destination, denotes COM port number

`udp_host` -- when UDP is set as destination, denotes IP address of a host to which messages will be sent

`udp_port` -- when UDP is set as destination, denotes port of a host to which messages will be sent

`log_format` -- syslog daemon will compose messages according to chosen format.

* 0 - RFC3164:

  ```cpp
  <priority>Mmm DD HH:MM:SS host tag[pid]: msg
  ```

  Example:

  ```cpp
  <165>Aug 24 05:14:15 192.0.2.1 myproc[8710]: hello world!
  ```
* 1 - RFC5424:

  ```cpp
  <priority>version YYYY-MM-DDTHH:MM:SS.MMMZ host proc pid msgid structured_data msg
  ```

  Example:

  ```cpp
  <165>1 2019-02-14T05:14:15.003Z 192.0.2.1 myproc 8710- - hello world!
  ```

{% hint style="info" %}
When you install the ADK release, the logging settings will be reset to the default values. This applies to both syslog settings and channel settings. If you need to keep your settings after installing an ADK release, you can use the liblog API and update the settings programmatically, or create a configuration package with your settings and install it right after the ADK release.
{% endhint %}

## Logging on android devices <a href="#sec_logging_android" id="sec_logging_android"></a>

As ADK-LOGGING project was initially made for VOS devices only, there are a few differences in the way logging works on android devices, therefore it has it's own section in documentation. To use ADK-LOGGING functions on android, liblog.so which is compiled for android-arm devices should be used. ADK logging configurations are stored on the device at /sdcard/config/adk-log/. Essentially usage is the same as on VOS devices (check out [Getting Started](#sec_logging_getting_started) for code example), but with some prerequisites:

### Android permissions necessary for logging <a href="#subsec_logging_android_permissions" id="subsec_logging_android_permissions"></a>

Starting from android 10 and up, android introduces scoped storage - this interferes with functionality of liblog, as it's primary functionality of reading configuration files from a specific directory was broken. For liblog.so to function properly (read configuration files) it is necessary to grant these android permissions for apps which want to use liblog (in `AndroidManifest.xml`):

Android 10 (NEO) devices need to grant `READ_EXTERNAL_STORAGE` permission and use `android:requestLegacyExternalStorage="true"` :

```cpp
<?xml version="1.0" encoding="utf-8"?>
  <manifest ...>
  ...
  <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
   <application android:requestLegacyExternalStorage="true">
   ...
   </application>
  </manifest>
</xml>
```

Android 13 (NEO2) and up need to request `MANAGE_EXTERNAL_STORAGE` permission to function properly:

```cpp
<?xml version="1.0" encoding="utf-8"?>
  <manifest ...>
  ...
  <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
  ...
  </manifest>
</xml>
```

Also, these permissions have to be requested programmatically for them to be granted (adding these permissions in the android manifest is not enough). Code simillar to this should be used to request those permissions:

```cpp
private static final int STORAGE_PERMISSION_CODE = 23;
public boolean checkStoragePermissions() {
   if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
   //Android is 11 (R) or above
   return Environment.isExternalStorageManager();
   } else {
   //Below android 11
   int write = ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
   int read = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE);
   return read == PackageManager.PERMISSION_GRANTED && write == PackageManager.PERMISSION_GRANTED;
   }
}
private void requestForStoragePermissions() {
   //Android is 11 (R) or above
   if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
   try {
   Intent intent = new Intent();
   intent.setAction(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
   Uri uri = Uri.fromParts("package", this.getPackageName(), null);
   intent.setData(uri);
   this.startActivity(intent);
   } catch (Exception e) {
   Intent intent = new Intent();
   intent.setAction(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
   this.startActivity(intent);
   }
   } else {
   //Below android 11
   ActivityCompat.requestPermissions(
   this,
   new String[] {
   Manifest.permission.WRITE_EXTERNAL_STORAGE,
   Manifest.permission.READ_EXTERNAL_STORAGE
   },
   STORAGE_PERMISSION_CODE
   );
   }
}
```

As it is best to not grant these dangerous permissions to apps, it is also possible to make liblog.so work by installing Log control panel for android. Log control panel shold be available on newest android NEO and NEO2 releases and it is possible to launch it from sysmode -> Other options -> Logging channels. Liblog.so has functionality to connect to LCP service to request config files without needing READ permissions, this means that LCP reads config files and sends this information to liblog.so to use for processing.

{% hint style="info" %}
If permissions are not granted to application which uses liblog and LCP is not installed on the device which runs android >=10, logging will not work! Either add above mentioned permissions, or install LCP and grant it MANAGE\_EXTERNAL\_STORAGE permissions on first run.
{% endhint %}

### Log control panel on Android <a href="#subsec_logging_log_control_panel_on_android" id="subsec_logging_log_control_panel_on_android"></a>

Latest android releases should have a LCP (Log control panel) application which adds possibility to add/modify/remove logging channels on the device and additionally has functionality to send config data to liblog if the application which uses liblog does not have read permissions. To launch LCP on android, open sysmode, press back arrow to enter "other options" menu and press "Logging channels" button. This should open LCP app.

| Screenshot                       | Additional info                                                                                                                                   |
| -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| ![](/files/m3dBsR2qtL45qyAXMfbu) | LCP can be opened by pressing "logging channels" button in sysmode "other options" menu.                                                          |
| ![](/files/tw0X3VwF29M5uMJboVMj) | Main menu of log control panel. Press "Add new channel" to add new config, or press on existing config to edit or delete selected entry.          |
| ![](/files/nICti68tXT13QBxSUySy) | LCP new config menu. press on editable fields to edit them (add name, state, logging level, etc.) and press "save channel" to save it, or cancel. |
| ![](/files/ikVca7171VgpSKNEthYg) | LCP edit config menu. Press on fields to edit them, possible to save channel or delete it.                                                        |

{% hint style="info" %}
As logcat has less levels of logging, some liblog logging levels share the same level in logcat. "EMERGENCY" and "ALERT" are printed as `ANDROID_LOG_FATAL`; "CRITICAL" and "ERROR" are printed as `ANDROID_LOG_ERROR`; "WARNING" and "NOTICE" are printed as `ANDROID_LOG_WARN`.
{% endhint %}

### How to obtain logs on Android <a href="#sec_logging_logs_on_android" id="sec_logging_logs_on_android"></a>

The logcat logging utility is a command-line tool included with the Android SDK that is used to obtain log on Android.

**Example**

```cpp
$ adb logcat
```

The utility allows to define a list of tags used in the system, with priorities, by running logcat and observing the first two columns of each message, given as \<priority>/\<tag>

The priority is one of the following character values, ordered from lowest to highest priority:

* V: Verbose (lowest priority)
* D: Debug
* I: Info
* W: Warning
* E: Error
* F: Fatal
* S: Silent (highest priority, on which nothing is ever printed)

Here's an example of a filter expression that suppresses all log messages except those with the tag "SYSCL", at priority "Verbose" or above, and all log messages with tag "TEST", with priority "Debug" or above:

```cpp
$ adb logcat SYSCL:V TEST:D *:S
```

## Storage Space, Log Cleanup, and Limits <a href="#sec_logging_cleanup" id="sec_logging_cleanup"></a>

By default, all log channels are disabled except for system logs, which are written to files (default destination). Log rotation periodically overwrites older files, enabling a relatively long log history with minimal flash space usage.

Two configuration options control log storage:

* `number_of_files`
* `max_logfile_size`

The default settings allow for 2 log files, each up to 2MB (200KB for VOS1/VOS2). Log rotation maintains 3 files (2 active + 1 in progress) to provide a history spanning 2 files.

For multiple debug-level channels enabled, the default may be insufficient and should be increased. However, setting very high values risks excessive flash usage.

In VOS3, automatic limits ensure logs do not consume all system data partition space. These adjust /c max\_logfile\_size to maintain at least 200MB of free system space.

In VOS3, applying new configurations may delete older logs if the current number of files or sizes on the flash exceed the set values. This can also be used to manually free up space: reducing /c max\_logfile\_size option will automatically remove all existing logs.

## Troubleshooting <a href="#sec_logging_troubleshooting" id="sec_logging_troubleshooting"></a>

One of the issues met by liblog user is that changing settings in LCP does not take an effect after editing existing logging channel or creating new one. Make sure to press 'Apply config' menu button to apply logging settings immediately. Otherwise these will be reread after next logging library initialization or after apropriate API function call.

![LCP Apply config](/files/RN9pFoocYCN7PgUxWHur)

## Appendix <a href="#sec_logging_appendix" id="sec_logging_appendix"></a>

### Known Issues and Limitations <a href="#subsec_logging_known_issues_and_limitations" id="subsec_logging_known_issues_and_limitations"></a>

Be aware of the following issues and limitations you may encounter:

* HOSTNAME part of syslog message is empty unless UDP is used as a destination.
* Some packets may be lost when using UDP due to the nature of the protocol.
* BOOT messages are not being converted to syslog format.
* `LOG_ODELAY`, `LOG_NDELAY`, `LOG_NOWAIT`, `LOG_PERROR` flags in `syslog.h` currently are not being used and are present for compatibility.
* Using printf-like macros (LOGF\*): passing NULL to string format specifier will cause a crash, e.g. LOGF\_TRACE("%s", NULL).
* Applying settings to syslog daemon make it restart and few messages are lost.

### Acronym Definitions <a href="#subsubsec_logging_acronym_definitions" id="subsubsec_logging_acronym_definitions"></a>

| Acronym | Definitions                    |
| ------- | ------------------------------ |
| ADK     | Application Development Kit    |
| API     | Application Protocol Interface |
| LCP     | Logging Control Panel          |
| OS      | Operating System               |
| V/OS    | Verifone Operating System      |


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://sandbox-docs.verifone.com/adk-5.0-programmers-guide/readme/system_overview/pg_all_components/pg_logging_users_guide.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
