# Logs

Source: https://docs.interop.io/insights/signals/logs/index.html

## Overview

Available since io.Connect Desktop 10.1

The Logs module of **io.Insights** bridges the existing io.Connect logging mechanisms with the OpenTelemetry log exporter, allowing platform and client app logs to be published as standard OpenTelemetry log records. Unlike metrics and traces, the Logs module doesn't provide its own API for generating log data - instead, it acts as a bridge between the io.Connect logging infrastructure (based on `log4js`) and the OpenTelemetry log pipeline.

In **io.Connect Desktop**, the logging architecture works as follows:

- The platform itself uses `log4js` for all internal logging. A custom `@interopio/log4js-otel` appender is included in the `log4js` configuration, which forwards log entries to the OpenTelemetry log exporter.
- Client web apps running in the platform publish logs through the io.Connect [Logger API](https://docs.interop.io/desktop/capabilities/logging/overview/index.md). These log entries are sent to the platform via the Interop method `T42.AppLogger.Log`, where they are routed through the same `log4js` pipeline and, if the OpenTelemetry appender is configured, exported as OpenTelemetry log records.
- Native apps (Node.js, .exe) can also have their `stdout` and `stderr` outputs captured and routed through the same logging pipeline.
- Additionally, the platform can capture console messages, network request errors, and unhandled JavaScript errors from web apps and route them through the logging pipeline.

This means that by enabling OpenTelemetry log publishing, all log data from the platform and its apps can be collected, filtered, and exported to an OpenTelemetry-compatible backend without any changes to the app code.

> ℹ️ *For details on configuring OpenTelemetry log publishing in **io.Connect Desktop**, see the [Configuration > io.Connect Desktop](https://docs.interop.io/insights/configuration/io-connect-desktop/index.md) section.*

> ℹ️ *For details on configuring the io.Connect logging mechanisms (log appenders, categories, per-app logging), see the **io.Connect Desktop** documentation on [System Configuration > Logging](https://docs.interop.io/desktop/developers/configuration/system/index.md#logging) and [Application Configuration > Logging](https://docs.interop.io/desktop/developers/configuration/application/index.md#logging).*

## Log Payload Structure

Logs are published as standard OpenTelemetry log payloads.

> ℹ️ *For more details on the standard structure of OpenTelemetry signals, see the [OpenTelemetry examples](https://github.com/open-telemetry/opentelemetry-proto/tree/main/examples) in GitHub.*

The following example demonstrates the basic structure of a logs payload:

```json
{
    "resourceLogs": [
        {
            "resource": {
                "attributes": [
                    // Attributes describing the resource publishing the logs -
                    // e.g., `"service.name"`, `"service.instance.id"`, and other standard OpenTelemetry attributes.
                ]
            },
            "scopeLogs": [
                {
                    "scope": {
                        "name": "default",
                        "version": ""
                    },
                    "logRecords": [
                        // List of log record objects.
                    ]
                }
            ]
        }
    ]
}
```

The following is an example of a log record object in the `"logRecords"` array:

```json
{
    "logRecords": [
        {
            "timeUnixNano": "1723555102580000000",
            "severityNumber": 9,
            "severityText": "INFO",
            "body": {
                "stringValue": "[2025-03-29 10:15:02.580] [INFO] [user_42] [hSzwWyE3TkdE5r-ZqmTq] [my-app] app-own-log - Loading configuration"
            },
            "attributes": [
                {
                    "key": "categoryName",
                    "value": {
                        "stringValue": "app-own-log"
                    }
                },
                {
                    "key": "applicationName",
                    "value": {
                        "stringValue": "my-app"
                    }
                },
                {
                    "key": "instanceId",
                    "value": {
                        "stringValue": "28_3"
                    }
                },
                {
                    "key": "loggerName",
                    "value": {
                        "stringValue": "my-app.services.config"
                    }
                }
            ],
            "traceId": "",
            "spanId": ""
        }
    ]
}
```

## Common Log Attributes

All logs published via **io.Insights** have the following common log attributes:

| Attribute | Description |
|-----------|-------------|
| `"categoryName"` | The `log4js` category that produced the log entry (e.g., `"default"`, `"app-own-log"`, `"gw"`). This attribute is used for [log filtering](https://docs.interop.io/insights/configuration/io-connect-desktop/index.md). |

All additional data point attributes provided via the platform configuration or dynamically via the Insights API will also be included in the respective data points. If the resource-level attributes are configured to be merged with the data point attributes, all resource-level attributes will also be included in every data point.

> ℹ️ *For details on the resource-level attributes common to all signals (metrics, traces, logs), see the [Signals > Overview > Common Resource Attributes](https://docs.interop.io/insights/signals/overview/index.md#common_resource_attributes) section.*

### Platform

Log records originating from the **io.Connect Desktop** platform itself (category `"default"` or `"glue-logger"`) carry the standard common attributes. The log body is formatted using the `log4js` layout pattern configured for the OpenTelemetry appender, which by default includes the timestamp, severity level, user, service instance ID, app name, and the log message.

### io.Connect Gateway

Log records originating from the io.Connect Gateway (category `"gw"`) carry the standard common attributes. The Gateway process has its own `log4js` configuration with an OpenTelemetry appender, and its logs are exported independently.

### Apps

Log records originating from client apps (category `"app-own-log"` or an app-specific category) have the following additional attributes set as `log4js` context values:

| Attribute | Description |
|-----------|-------------|
| `"applicationName"` | The name of the app within the io.Connect framework that produced the log entry (e.g., `"my-app"`). |
| `"instanceId"` | The unique ID of the app instance that produced the log entry (e.g., `"28_3"`). |
| `"loggerName"` | The name of the logger used by the app to produce the log entry (e.g., `"my-app.services.config"`). For captured console messages, this is `"console-messages"`. For captured network request errors, this is `"web-request"`. For captured unhandled errors, this is `"unhandled-error"`. For captured `stdout`/`stderr` from native apps, this is `"std"`. |
