> ## Documentation Index
> Fetch the complete documentation index at: https://docs.appsignal.com/llms.txt
> Use this file to discover all available pages before exploring further.

# JSON Log Formatting

<Warning>
  🔐 Do not send <strong>Personal Identifiable Information (PII)</strong> to AppSignal. Filter PII (e.g., names, emails) from logs and use an ID, hash, or pseudonymized identifier instead. <br /> <br /> For **HIPAA-covered entities**, more information about signing a Business Associate Agreement (BAA) can be found in our [Business Add-Ons documentation](/support/business-add-ons).
</Warning>

This documentation explains how AppSignal supports log messages formatted in JSON.

## JSON

If you specify JSON as your log format, AppSignal will parse incoming log `message` as key-value pairs. Each key-value pair will be stored as an attribute on the log line, allowing you to filter and search for specific log lines based on their attributes.

### Examples

The following example shows how AppSignal parses a log `message` in the JSON format.

<CodeGroup>
  ```json JSON theme={null}
  {
    "timestamp": "2022-06-02T04:17:25.783Z",
    "group": "organisations",
    "severity": "warn",
    "hostname": "frontend1",
    "message": "This is a test message",
    "org": "appsignal",
    "step": 1,
    "seen_terms": true,
    "entries": 10.01,
    "user": { "id": 1, "remote_id": "123" }
  }
  ```
</CodeGroup>

#### Message

The above JSON will be parsed with the message `"this is a test message"`.
You can either use the `msg` or `message` key to override the message.

If no `msg` or `message` key is available, the entire log line will be used as the message.

#### Overrides

The log attributes from the platform or integration (such as hostname, timestamp and group set by e.g. the Heroku platform) can be overridden with the values from the JSON message.

| Attribute Key | Type     |
| ------------- | -------- |
| group         | String   |
| severity      | Severity |
| hostname      | String   |
| message       | String   |

The `severity` can contain one of the following values: `unknown`, `trace`, `debug`, `info`, `notice`, `warn`, `error`, `critical`, `alert` and `fatal`.

This is an excellent way to control the severity of your log lines from within application, regardless of the (usually defaulted `info`) severity set by the platform or integration.

#### Attributes

Any other key/value pair is added as a searchable attributes:

| Attribute Key   | Type   | Value       |
| --------------- | ------ | ----------- |
| org             | String | "appsignal" |
| step            | Int    | 1           |
| seen\_terms     | Bool   | true        |
| entries         | Double | 10.01       |
| user.id         | Int    | 1           |
| user.remote\_id | String | "123"       |

## Formatting Rules

<Note>
  Keys must be alphanumeric strings. Array values are not supported.
</Note>

**Key behavior:**

* If a key-value pair has a key with the name of `msg` or `message` the value of this key will be parsed as the log message.
* If no message/msg key is available, the entire log line will be considered the message.
* Keys must be alphanumeric.
* Keys cannot contain spaces, but may contain full stops (`.`), underscores (`_`) and hyphens (`-`).
* Keys may not contain more than 50 characters

**Value behavior:**

* Values must not be longer than 255 characters
* No more than 25 attributes per log message.
* Values may contain nested Objects, but not Arrays.
* Values may be of the following types:
  * String
  * Integer (e.g. `10`)
  * Double (e.g. `10.01`)
  * Boolean (`true`/`false`)
  * Object (e.g. `{ "foo": "bar" }`)

For nested objects, the attributes will be flattened, separated by a `.` character.

Key value pairs that do not follow these rules are appended to the message of a log, unless a `message` or `msg` key is provided.
