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

# Events

> Learn about ngrok's event logging system for exporting traffic logs, audit logs, and configuration changes to external services.

## Overview

Whenever changes occur in your ngrok account or when traffic transits through
your endpoints, a log is generated. You may export these logs and in some cases, filter
them to those relevant to you and publish them to any number of destinations.

ngrok's logging system was designed for three primary use cases:

* Sending logs of your ngrok traffic to external services such as Datadog and
  Amazon CloudWatch Logs
* Sending audit logs of ngrok configuration changes to your SIEM
* Enabling you to programmatically respond to events on your ngrok account

There are [over 40 log sources published](/obs/events/reference) via ngrok at the time of writing.
They break down into two important classes of logs:

* **[Traffic Logs](/obs/events/reference/#traffic-events)**: When traffic transits through your endpoints like processing an HTTP request or TCP connection
* **[Audit Logs](/obs/events/reference/#audit-events)**: Changes to your account like create/update/delete of Domains, API Keys, IP Policies, etc.

## Concepts

ngrok's logging system is composed of three simple primitives. You create
a **Log Export** to *subscribe* to a set of **Log Sources** and
*publish* those logs to one or more **Log Destinations**.

* **[Log Exporting](#log-exporting)**: Define which Log
  Sources to capture and which Log Destinations to publish to.
* **[Log Sources](#sources)**: The ngrok log types to capture and
  optionally a set of fields to record and a boolean filter expression.
* **[Log Destinations](#destinations)**: Where logs are sent, for example,
  Datadog, CloudWatch, Kinesis.

## Quickstart

You can create your first Log Export on the [Log Exporting page of your ngrok
Dashboard](https://dashboard.ngrok.com/log-exporting) to begin capturing
and publishing logs.

Guides are also published to get started with each of ngrok's Log Destinations:

* **[AWS CloudWatch Logs](/integrations/event-destinations/amazon-cloudwatch-event-destination)**
* **[AWS Firehose](/integrations/event-destinations/amazon-firehose-event-destination)**
* **[AWS Kinesis](/integrations/event-destinations/amazon-kinesis-event-destination)**
* **[Azure Logs Ingestion](/integrations/event-destinations/azure-logs-event-destination)**
* **[Datadog Logs](/integrations/event-destinations/datadog-event-destination)**

## Log exporting

A Log Export defines which [Log Sources](/obs/events/reference/) to capture and which
destinations to publish to. If you're familiar with other logging systems, they may
call this a *listener*, a *hook*, a *probe* or a *tap*.

When you create a Log Export, you select:

* One or more Log Sources to subscribe to
* One or more Log Destinations to publish the subscribed logs to

Log Exports can be created on the [ngrok
Dashboard](https://dashboard.ngrok.com/events/subscriptions) or via the [
Log Exporting API Resource](/api-reference/eventsubscriptions/create).

## Log sources

Log Sources choose which logs a Log Export captures. Other logging
systems may call this a *selector*.

The [ngrok Log Sources reference](/obs/events/reference) documents the full list
of Log Sources and their fields.

### Versioning and payload stability

Log Sources include a version number in their name. Each Log Source ends
with a version string after a dot, for example, `api_key_created.v0`.

New fields may be added to the payloads of a Log Source without a version
change. Any other change to the log representation will lead to the
introduction of a new version of the Log Source.

### Audit logs

ngrok emits [Audit Logs](/obs/events/reference/#audit-events) when changes are made to
your account like create/update/delete of Domains, API Keys, IP Policies, etc.

### Traffic logs

When traffic transits through your endpoints, ngrok emits [Traffic
Logs](/obs/events/reference/#traffic-events) like processing an HTTP request or TCP
connection.

Traffic Logs support the ability to select exactly which fields you'd like to
include in the captured log. This provides you with control over how much
data is sent to the destinations.

Traffic Logs also support the ability to be **filtered**. As part of the Log Source
definition you can specify a CEL expression which is evaluated against each log
to determine if it should be captured. See the [Filters](#filters) section
for further detail.

#### Filters

You may specify a filter on [Traffic
Logs](/obs/events/reference/#traffic-events) since the velocity of these logs can be quite high. Filters are a boolean
expression defined in [Google's Common Expression Language
(CEL)](https://github.com/google/cel-spec/blob/master/doc/langdef.md#standard).
Filters are evaluated on each log as it is published to determine whether it
should be sent to the Log Export's destinations.

Traffic Logs are often high cardinality. Filters are supported because you may
only be interested in logging a subset of traffic (for example, specific client IPs).
Filters also enable you to control spend on downstream destinations where you
incur costs based on the quantity of data processed and stored.

The log object is made available to the CEL filter expression as the `ev`
variable. `ev` corresponds to the `object` field of the captured log. Use
standard [JSONPath](https://goessner.net/articles/JsonPath/) syntax to access
the fields of the log you want to use in your filters.

Filter expressions have the following limitations:

* Only some fields of an log are available in the `ev` object. The Log
  Source's reference documentation will specify whether a field may be evaluated
  in a filter expression.
* Log metadata fields like `principal` or `event_timestamp` are not available

#### Filter examples

###### Filter for connections from a particular hostname

```cel theme={null}
ev.conn.server_name.matches("ngrok-docs-examples\\.ngrok\\.dev")
```

###### Filter for connections to an endpoint that didn't use HTTPS

```cel theme={null}
ev.conn.server_name.matches(".*-your-org\\.ngrok\\.dev") &&
ev.conn.server_port == 80
```

###### Filter for connections to a hostname that exclude traffic from a client IP

```cel theme={null}
ev.conn.client_ip != "2601:0:8200:0:4cd7:fd52:0:7823" &&
ev.conn.server_name == "ngrok-docs-examples.ngrok.dev"
```

## Log destinations

An Log Destination encapsulates the configuration to publish logs to other
systems. Other logging systems may call this a *sink* or *output*.

Log Destinations are typically third-party logging aggregators. The following
destinations are currently supported:

* [Amazon CloudWatch](/integrations/event-destinations/amazon-cloudwatch-event-destination)
* [Amazon Firehose](/integrations/event-destinations/amazon-firehose-event-destination)
* [Amazon Kinesis](/integrations/event-destinations/amazon-kinesis-event-destination)
* AWS S3 (via Kinesis Firehose)
* [Azure Logs Ingestion](/integrations/event-destinations/azure-logs-event-destination)
* [Datadog Logs](/integrations/event-destinations/datadog-event-destination)

Each destination requires provider-specific configuration. If you create a
destination in the ngrok dashboard, you'll be prompted to send a test log to
verify the integration.

<Note>
  When configuring AWS destinations you'll be prompted to optionally download a
  small helper script which will automatically configure the appropriate IAM
  objects necessary for integration. You may also set these values up via the AWS
  Console or tools like Terraform or Pulumi.
</Note>

Amazon S3 is not a directly supported destination. Instead, configure Amazon Firehose to
[deliver logs into an S3
bucket](https://docs.aws.amazon.com/firehose/latest/dev/create-destination.html#create-destination-s3).

## Log payloads

Logs are serialized as JSON when they are published to a destination.

All logs include the following fields:

| Name              | Description                                                            | Example                          |
| ----------------- | ---------------------------------------------------------------------- | -------------------------------- |
| `account_id`      | unique identifier for the account, always prefixed with ac\_           | `ac_2OtNvAlhso10Gx6s7eupzX3F98q` |
| `event_id`        | unique identifier for this log, always prefixed with ev\_              | `ev_1vPlyBW3OR44bpPphS4HIZyajDD` |
| `event_type`      | identifies the object, action, and version of the log                  | `ip_policy_created.v0`           |
| `event_timestamp` | timestamp of when the log fired in RFC 3339 format                     | `2021-07-16T21:44:37Z`           |
| `object`          | the log object                                                         | See examples below               |
| `principal`       | an object of the principal who emitted this log, null for traffic logs | See example below                |

The `object` property of the log is distinct for each Log Source and contain a JSON object with additional information about the log.

For [Audit Logs](/obs/events/reference#audit-events), the `object`
representation is identical to its API resource at the time of capture.

[Traffic Logs](/obs/events/reference#traffic-events) define their own `object`
representation because they have no corresponding API resource definition.

#### Principal object

The `principal` object in every log describe the user or Service User responsible
for initiating the log. Principal is defined for all Audit Logs
and it is `null` for Traffic Logs (since they do not include a credential).

| Name       | Description                                                                                       | Example                                                                                                           |
| ---------- | ------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
| id         | unique identifier for the principal, either a user or Service User                                | `usr_2OtNv9qH5Nk4NuNeszZ39gBxZ4H`                                                                                 |
| subject    | human readable unique identifier for the principal, either a user email or a Service User name    | `foo@example.com`                                                                                                 |
| source     | where the principal initiated the log, either 'Dashboard' or 'API'                                | `API`                                                                                                             |
| credential | id and uri resource for the credential used for authentication, `null` if `source` is 'Dashboard' | `{"id": "ak_2Oxt94wYsBTLwFUoMZcJRvJTaub","uri": "https://api.ngrok.com/api_keys/ak_2Oxt94wYsBTLwFUoMZcJRvJTaub"}` |

### Example payloads

#### [ip\_policy\_created.v0](/obs/events/reference/#ip-policy) log

```json theme={null}
{
	"event_id": "ev_25X2AsJ5xpvuOParTYUQWe12XKo",
	"event_type": "ip_policy_created.v0",
	"event_timestamp": "2022-02-23T23:29:29Z",
	"account_id": "ac_2OtNvAlhso10Gx6s7eupzX3F98q",
	"principal": {
		"id": "usr_2OtNv9qH5Nk4NuNeszZ39gBxZ4H",
		"subject": "foo@example.com",
		"source": "API",
		"credential": {
			"id": "ak_2Oxt94wYsBTLwFUoMZcJRvJTaub",
			"uri": "https://api.ngrok.com/api_keys/ak_2Oxt94wYsBTLwFUoMZcJRvJTaub"
		}
	},
	"object": {
		"id": "ipp_25X2Ao39z73FlVQKZ1iReMPe6Qv",
		"uri": "https://api.ngrok.com/ip_policies/ipp_25X2Ao39z73FlVQKZ1iReMPe6Qv",
		"created_at": "2022-02-23T23:29:29Z",
		"description": "Home network IP",
		"metadata": "",
		"action": "allow"
	}
}
```

#### [http\_request\_complete.v0](/obs/events/reference/#http-request-complete) log

```json theme={null}
{
	"event_id": "ev_25X3yFS6TDkig1KDJWIc4nnJO0c",
	"event_type": "http_request_complete.v0",
	"event_timestamp": "2022-02-23T23:44:16Z",
	"account_id": "ac_2OtNvAlhso10Gx6s7eupzX3F98q",
	"object": {
		"conn": {
			"client_ip": "2601:0:8200:9e:4cd7:0:c97f:7823",
			"server_name": "ngrok-docs-example.ngrok.app",
			"server_port": ""
		},
		"http": {
			"request": {
				"first_byte_ts": null,
				"last_byte_ts": null,
				"method": "GET",
				"url": {
					"path": "/docs/obs"
				},
				"version": "HTTP/2.0"
			},
			"response": {
				"body_length": 13079,
				"first_byte_ts": "2022-02-23T23:44:16.732791273Z",
				"last_byte_ts": "2022-02-23T23:44:16.737257209Z",
				"status_code": 200
			}
		}
	}
}
```

#### [tcp\_connection\_closed.v0](/obs/events/reference/#tcp-connection-closed) log

```json theme={null}
{
	"event_id": "ev_25X4osod1q306srserDeFyghTC4",
	"event_type": "tcp_connection_closed.v0",
	"event_timestamp": "2022-02-23T23:51:14Z",
	"account_id": "ac_2OtNvAlhso10Gx6s7eupzX3F98q",
	"object": {
		"conn": {
			"bytes_in": 3437,
			"bytes_out": 90256,
			"client_ip": "2601:0:8200:9e:4cd7:0:c97f:7823",
			"end_ts": "2022-02-23T23:51:14.005372199Z",
			"server_name": "ngrok-docs-example.ngrok.app",
			"server_port": "",
			"start_ts": "2022-02-23T23:44:16.528374173Z"
		}
	}
}
```

## Events pricing

Log Exports are available to free and Pay-as-you-go plans. For more details, see the [ngrok pricing](https://ngrok.com/pricing) page.

The Traffic Inspector is included with all ngrok accounts with a
retention period starting at 1 day and going up to 3 days. An additional 90 days can be purchased as
an add-on to the Pay-as-you-go plan. For more details, see the [ngrok pricing](https://ngrok.com/pricing) page.
