Vai al contenuto

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:

Field Description Level
error.code Error code describing the error.

type: keyword
core
error.id Unique identifier for the error.

type: keyword
core
error.message Error message.

type: text
core
error.stack_trace The stack trace of this error in plain text.

type: keyword

Multi-fields: error.stack_trace.text (type: text)
extended
error.type The type of the error, for example the class name of the exception.

type: keyword

example: java.lang.NullPointerException
extended

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).

!!! 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.

!!! 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 Level Field
Incoming request trace host, url, user_agent
Request completed info host, http, response_time, url, user_agent

!!! 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.

!!! None of the fields below is mandatory.

Host

Field Description Level
host.hostname Hostname of the host.

It normally contains what the hostname command returns on the host machine.

type: keyword
core
host.name Name 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: keyword
core
host.uptime Seconds the host has been up.

type: long

example: 1325
extended

HTTP

Field Description Level
http.request.body.bytes Size in bytes of the request body.

type: long

example: 887
extended
http.request.bytes Total size in bytes of the request (body and headers).

type: long

example: 1437
extended
http.request.method HTTP request method.

The field value must be normalized to lowercase for querying. See the documentation section "Implementing ECS".

type: keyword

example: get, post, put
extended
http.request.referrer Referrer for this HTTP request.

type: keyword

example: https://blog.example.com/
extended
http.response.body.bytes Size in bytes of the response body.

type: long

example: 887
extended
http.response.bytes Total size in bytes of the response (body and headers).

type: long

example: 1437
extended
http.response.status_code HTTP response status code.

type: long

example: 404
extended
http.version HTTP version.

type: keyword

example: 1
extended

URL

Field Description Level
url.domain Domain 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.co
extended
url.fragment Portion of the url after the #, such as "top".

The # is not part of the fragment.

type: keyword
extended
url.full If 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#top
extended
url.path Path of the request, such as "/search".

type: keyword
extended
url.port Port of the request, such as 443.

type: long

example: 443
extended
url.query The 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: keyword
extended
url.scheme Scheme of the request, such as "https".

Note: The : is not part of the scheme.

type: keyword

example: https.
extended

User Agent

Field Description Level
user_agent.device.name Name of the device.

type: keyword

example: iPhone
extended
user_agent.name Name of the user agent.

type: keyword

example: Safari
extended
user_agent.original Unparsed 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.1
extended
user_agent.version Version 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.