Version: 5.10.x

Guidelines for logs

The objective of these guidelines is to guarantee uniformity in the logs generated by the platform and, thus, to ensure an easy usage.

Logs are generated according to Elastic Common Schema specifications.

Guidelines#

The following are guidelines, drawn from guidelines and best practices suggested by Elastic, which have to be followed when application logs are generated:

  • Field names have to be in camelCase;

  • Field names does not have to contain special characters;

  • Field names have to properly be used in the singular or plural form according to the content of the field itself;

  • For custom fields use, where it makes sense, nesting in objects;

  • Avoid using abbreviations in field names as much as possible.

Message#

The text message passed to the log is, by default, inserted in the key message, if only one object is passed to the logger. Make sure that the key used for the message is the same.

Errors#

When an error log is generated, the passed object must necessarily have the key error, whose value has to be an object of the form specified by ECS for the Error Fields, which are shown in the table below:

FieldDescriptionLevel
error.codeError code describing the error. type: keywordcore
error.idUnique identifier for the error. type: keywordcore
error.messageError message. type: textcore
error.stack_traceThe stack trace of this error in plain text. type: keyword Multi-fields: error.stack_trace.text (type: text)extended
error.typeThe type of the error, for example the class name of the exception. type: keyword example: java.lang.NullPointerExceptionextended

NB: none of the fields is mandatory, however it is important not to use custom keys.

Use the appropriate logging level#

There are 6 debug levels: trace, debug, info, warning, error, fatal.

It is important to always use the correct level; to choose which is the appropriate level, one should rely on the following criteria:

  • fatal: in cases of unexpected and not recoverable error, and as a result of which the service must stop its execution;

  • error: in cases of not recoverable error and error for which the processing of the request (but not the service) must be interrupted;

  • warning: in cases of recoverable error, the service can continue to process the request;

  • info: in cases where the service has to give information about the branch of code in execution, in general this type of log should be strictly necessary;

  • debug: to report information that may be useful in troubleshooting (do not use in production);

  • trace: to trace the operations flow of the application (do not use in production).

warning

It is important to enter in the logs the right information that is used to track operations, highlight problems and allow troubleshooting. It is equally important to pay close attention to what is entered in the logs, avoiding, in any case, to insert in the messages or in the custom properties of the log, any value that can lead to privacy data.

Mandatory Logs#

Each core service must necessarily generate the logs of the table below.

note

Generally, the management of these logs is entrusted to internal libraries:

  • for the services ## Node.js## , they will be managed by lc39 and custom-plugin;
  • for the services ## Go## , they will be managed by glogger;
  • for the services ## Kotlin## and ## Java## , instead, there are no internal libraries nowadays: custom implementations must be made.
## Event##LevelField
Incoming requesttracehost, url, user_agent
Request completedinfohost, http, response_time, url, user_agent
note

If the service is not REST but takes its inputs from another source, the same criterion is applied; use a log trace when the processing event starts and a log info when the event ends; the final log has to contain as much useful information as possible.

Mandatory Fields#

In each log, the following fields have to be always present:

  • request_id: taken from the platform headers and necessary to trace the flow of each request;

  • time: that signals the moment when it was generated in ISO 8601 format.

Field ECS Definition#

The fields host, http, url e user_agent have to maintain the format specified in ECS; the available parameters are reported here.

info

None of the fields below is mandatory.

Host

FieldDescriptionLevel
host.hostnameHostname of the host. It normally contains what the hostname command returns on the host machine. type: keywordcore
host.nameName of the host. It can contain what hostname returns on Unix systems, the fully qualified domain name, or a name specified by the user. The sender decides which value to use. type: keywordcore
host.uptimeSeconds the host has been up. type: long example: 1325extended

HTTP

FieldDescriptionLevel
http.request.body.bytesSize in bytes of the request body. type: long example: 887extended
http.request.bytesTotal size in bytes of the request (body and headers). type: long example: 1437extended
http.request.methodHTTP request method. The field value must be normalized to lowercase for querying. See the documentation section "Implementing ECS". type: keyword example: get, post, putextended
http.request.referrerReferrer for this HTTP request. type: keyword example: https://blog.example.com/extended
http.response.body.bytesSize in bytes of the response body. type: long example: 887extended
http.response.bytesTotal size in bytes of the response (body and headers). type: long example: 1437extended
http.response.status_codeHTTP response status code. type: long example: 404extended
http.versionHTTP version. type: keyword example: 1extended

URL

FieldDescriptionLevel
url.domainDomain of the url, such as www.elastic.com. In some cases a URL may refer to an IP and/or port directly, without a domain name. In this case, the IP address would go to the domain field. type: keyword example: www.elastic.coextended
url.fragmentPortion of the url after the #, such as "top". The # is not part of the fragment. type: keywordextended
url.fullIf full URLs are important to your use case, they should be stored in url.full, whether this field is reconstructed or present in the event source. type: keyword Multi-fields: url.full.text (type: text). example: https://www.elastic.co:443/search?q=elasticsearch#topextended
url.pathPath of the request, such as "/search". type: keywordextended
url.portPort of the request, such as 443. type: long example: 443extended
url.queryThe query field describes the query string of the request, such as "q=elasticsearch". The ? is excluded from the query string. If a URL contains no ?, there is no query field. If there is a ? but no query, the query field exists with an empty string. The exists query can be used to differentiate between the two cases. type: keywordextended
url.schemeScheme of the request, such as "https". Note: The : is not part of the scheme. type: keyword example: https.extended

User Agent

FieldDescriptionLevel
user_agent.device.nameName of the device. type: keyword example: iPhoneextended
user_agent.nameName of the user agent. type: keyword example: Safariextended
user_agent.originalUnparsed user_agent string. type: keyword Multi-fields: user_agent.original.text (type: text) example: Mozilla/5.0 (iPhone; CPU iPhone OS 12_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0 Mobile/15E148 Safari/604.1extended
user_agent.versionVersion of the user agent. type: keyword example: 12.0.extended

Automatic Operations#

FluentBit Mappings#

For backwards compatibility issues, FluentBit will be configured to remap certain keys:

  • @timestamp will be taken from the field time;

  • msg and err will be remapped with the message and error standards (or error.message if err is a string);

  • reqId (and possible variants, such as requestId and request_id) will be remapped on tracing.id.

Information on the container#

ECS expects fields related to information on the container from which the logs were generated; we expect to be able to extract this information during the log recovery phase, in particular container.labels, container.id, container.name and container.annotations.