# Anomaly detection Source: https://docs.appsignal.com/anomaly-detection With [Anomaly detection](https://appsignal.com/redirect-to/app?to=alerts), you can configure Triggers to send notifications when a metric value goes over or dips below a threshold value. For example: When the error rate of an application goes over 5 % or free memory dips below 100MB. Anomaly detection works by detecting changes in metric values on a minutely basis. When a threshold condition is reached, we will notify you of the new alert created by this event and notify you again when the threshold is no longer being reached. To ensure you are being alerted at a time that suits you, you can define [warm-ups and cooldowns](#warm-up-and-cooldown) to control when a new alert is opened. ## Alert states Alerts can have five different states: | State | Description | | ---------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | | Warming up | The Alert is in it's warm-up phase. You can configure per Trigger that a condition has to be true for a specified amount of time before you get alerted. | | Open | The Alert has become active because it has reached its threshold condition. | | Closed | The alert is no longer active, and has been closed. | | Cool Down | The Alert is no longer over its threshold condition but will not be ended or re-opened until the end of the cooldown duration. | | Ended | The Alert is ended. No further alert will be sent. If the triggers conditions are triggered again, a new alert will enter the warming up phase. | Alert States ### When will I be notified? After you've configured notifications, you will be notified when an alert goes into the open phase. You will be notified by any reminders you configured during that phase and when the Alert is closed. ### Email alerts Alert emails will include an overview of new alerts, reminders, and the status of other alerts that have yet to end. ## Creating and configuring triggers Anomaly detection can be configured per app in the ["Anomaly detection" section](https://appsignal.com/redirect-to/app?to=alerts) in the app navigation. By default you will see the latest alerts created by triggers that you've configured for the app. In the top navigation you can switch to the [triggers page](https://appsignal.com/redirect-to/app?to=triggers) to create new and edit existing triggers. You can create and manage Triggers from the ["Anomaly detection" section](https://appsignal.com/redirect-to/app?to=triggers) of your application's navigation menu. Creating a trigger You can configure Triggers with a variety of metrics: * Error rates * Error (absolute) counts * App throughput * Performance of actions (slow actions) * Queue time * Host metrics * CPU load * Disk I/O * Disk usage * Load averages * Memory usage * Network usage ### Warm-up and cooldown You can configure warm-up and cooldown settings for each trigger, allowing you to define the time the system waits before opening and closing an alert. ### Warm-up It's not recommended to use Anomaly detection and the Warmup feature to check if services such as hourly/daily jobs and cronjobs are running. Typically when a Trigger's threshold condition is reached, it opens an Alert; for example, the error rate is higher than 5%. When a warm-up period has been configured on the Trigger AppSignal will only open an alert once that time has passed and if the threshold trigger is still met; for example, the error rate is higher than 5% for more than 3 minutes. When a trigger has a warm-up period configured, the alert will only open once the warm-up time has passed. The threshold condition must be met for the entire warm-up period for the alert to open. AppSignal will notify you when the alert status shifts from warm-up to open. ### Cooldown Alerts opened by a Trigger are automatically closed when the threshold condition is no longer met. To avoid being overly notified, you can configure cooldown periods. If you have configured a cooldown period for a Trigger, a new alert will not be created unless the Trigger's conditions are met after the cooldown period has expired. For example: 1. An Alert is opened because the error rate is higher than 5% 2. The error rate drops, so the alert is automatically closed. 3. The trigger for the alert has a two-minute cooldown period. 4. The error rate goes above 5% again. 5. AppSignal will not create a new alert unless the error rate exceeds 5% after the cooldown period ends. ### Tags Some metrics require tags to be selected as well. For example, if you are sending a custom metric to AppSignal that has tags: ```ruby Ruby theme={null} Appsignal.set_gauge("my_metric_name", 100, :namespace => "web", :action => "hello") ``` Then while creating a Trigger for this metric you need to select tags as well. Trigger with tags ## Missing datapoints as 0 By default, Triggers assume that a data point is sent every minute. This may not be feasible in certain situations, such as incrementing a counter only if a specific action occurs. In such cases, you can use the option `"When checked, we will treat missing datapoints as a value of 0"`. Enabling this option will cause the system to assume that a missing data point has a value of zero. This will help ensure the alert closes as expected if no data is received in the next minute. ## Data processing The metrics used by triggers to create alerts are not instantly processed when the metrics are sent from your application to AppSignal. Your metrics data will go through multiple systems before it arrives at our processor. The data may also be sent from multiple servers that [send data at different intervals](/appsignal/how-appsignal-operates#agent). The processor then waits\* until all the data for a minute has arrived before processing that data and creating or updating alerts. If you experience problems with the metrics being reported by AppSignal for Anomaly detection, ensure that your application's servers are all reporting simultaneously by configuring them using [NTP](https://en.wikipedia.org/wiki/Network_Time_Protocol). Incorrect or different reported times for data sent by multiple app servers can result in Alerts never being opened or closed. You can learn more about how AppSignal processes data for Anomaly detection and what this means for the alerts in our [data life cycle documentation][data life cycle]. \*: For more information on wait time specifics, consult our [data life cycle page][data life cycle]. [data life cycle]: /appsignal/data-life-cycle.html ## Managing incidents You can view all alert incidents on the Anomaly Issues page in the AppSignal app. The Issues page displays an overview of all open alert incidents, ordered by their last occurrence, with columns for the anomaly: * Name * Status * Assignees * State * Last state change time You can also easily filter your incidents based on their [state](#alert-states). Overview of alert incidents To investigate an incident further, you can open the incident summary. Here you'll find all the tools and information needed to investigate further the anomaly triggering your alert. On the summary page, you will have access to: * **Alert information:** The metric name, alert state, and tags of the alert. * **Occurrence frequency graph:** A visual representation of the alert's occurrence. * **Incident Settings:** Ability to close the alert, set its severity, and assign it to a team member. * **Trigger Information:** The conditions required to trigger the alert. * **Latest occurrences:** A table of the most recent occurrences, with their start/end time, state, and peak value. * **Logbook:** A logbook for logging important alert information about this alert for your team or future self. * **Access to the Time Detective:** Use the Time Detective tool to view the state of your application when the alert last occurred. All of these features are easily accessible in our intuitive UI: Overview of alert incident page # API overview Source: https://docs.appsignal.com/api ## Base endpoint The base endpoint for all API calls is `/api` on the `appsignal.com` domain. ```shell Shell theme={null} https://appsignal.com/api ``` ## Responses The response type supported by the AppSignal API is JSON. On some endpoints JSONP is also supported. Make sure all requests to endpoints end with the `.json` extension so no URLs will have to be updated in the future. ## Authentication | Parameter | Type | Description | | --------- | ---------------- | ---------------------: | | token | string, required | Your personal API key. | All requests to AppSignal API endpoints require a personal API `token` given as an URL query parameter for authentication. ```shell Shell theme={null} https://appsignal.com/api/[endpoint].json?token=personal_api_key ``` (Replace `[endpoint]` with the endpoint you need.) Your personal API key can be found on the [personal settings screen](https://appsignal.com/users/edit). ## Applications | Parameter | Type | Description | | --------- | ---------------- | -------------: | | app\_id | string, required | Application id | All endpoints provided by our API are scoped on application-level, not on organization-level (more than one application). For the API to know what data to return from which application the application id needs to be provided in the endpoint URL. For example, given this string in the API documentation: ```shell Shell theme={null} /api/[app_id]/samples.json ``` The URL becomes: ```shell Shell theme={null} https://appsignal.com/api/5114f7e38c5ce90000000011/samples.json?token=abc ``` The `app_id` for an application can be found in the URL of the [AppSignal.com](https://appsignal.com/accounts) when an application is opened. For legacy reasons the URL will mention `/sites` rather than `/applications`. The id that follows is your application id. ```shell Shell theme={null} https://appsignal.com/demo-organization/sites/5114f7e38c5ce90000000011 ``` # Event names Source: https://docs.appsignal.com/api/event-names AppSignal instrumentation creates events for pieces of code that are instrumented. These events are used to calculate the code execution duration and Garbage Collection of separate libraries and code blocks. Instrumenting allows AppSignal to detect problem areas in code. It makes it possible to see if an application's database queries are slow or if a single API call is causing the most slow down in a request. To instrument code accurately every event name follows a very specific naming method. Picking a good name can help a lot with how AppSignal processes and displays the incoming data. Naming events can be difficult, but hopefully this short explanation of how an event name is used will help you with picking a good one. For more about instrumentation read more in our Custom instrumentation guides: * [Ruby custom instrumentation](/ruby/instrumentation/instrumentation) * [Elixir custom instrumentation](/elixir/instrumentation/instrumentation) * [Node.js custom instrumentation](/nodejs/3.x/instrumentation/instrumentation) * [Python custom instrumentation](/python/instrumentation/instrumentation) ## Event groups Every event created by AppSignal instrumentation has a name. In this name the parent group of an event is also present. This group name allows AppSignal to group together events from database queries and view rendering. Using this grouping we can create overviews that show execution times per group as well as single events. For example, our Rails integration creates these groups: `active_record`, `action_view`, `action_controller`, etc. ## Event naming An event name is a string consisting of alphanumeric characters, underscores and periods. Spaces and dashes are not accepted. Think of this regex, `([a-zA-Z0-9_.]+)`, if it is accepted by this regex the event name is accepted. Let's start with a simple event name. ```shell Shell theme={null} sql.active_record ^ ^ | second part (group) first part (action) ``` The action of an event name is everything until the last period `.` in a key. The group is everything after this period. The group of an event is the code library it belongs to or the kind of action it is, such as a database query or HTTP request. It also works with multiple periods in a key. ```shell Shell theme={null} fetch.partition3.database ^ ^ | second part (group) first part (action) ``` We use this last-naming-scheme for the [Ruby method instrumentation](/ruby/instrumentation/method-instrumentation) ourselves. When a name with just one part is encountered the event will automatically be grouped under the `other` group. ## Examples Some examples of keys that are used by AppSignal integrations: * ActiveRecord: `sql.active_record` * Redis: `query.redis` * Elasticsearch: `search.elasticsearch` * ActionView: `render_template.action_view` and `render_partial.action_view` * Ruby's Net::HTTP: `request.net_http` * Sidekiq: `perform_job.sidekiq` * [Ruby method instrumentation](/ruby/instrumentation/method-instrumentation): * `method_name.ClassName.other`, and; * `method_name.class_method.NestedClassName.ParentModule.other` # GraphQL API Source: https://docs.appsignal.com/api/graphql AppSignal provides a GraphQL API that allows you to programmatically query your application data, including incidents, deployments, metrics, uptime monitors, etc. ## Endpoint The GraphQL API endpoint is available at: ```shell Example theme={null} https://appsignal.com/graphql?token=your-personal-api-token ``` ## Authentication All requests require a personal API token passed as a query parameter. You can find your API token in the [personal settings screen](https://appsignal.com/users/edit) in AppSignal. ## Application ID Most queries require your application ID, which can be found in your app's [settings screen](https://appsignal.com/redirect-to/app?to=admin/api_keys). ## GraphQL Explorer You can explore the API using an external GraphQL client like [Cloud Hasura's GraphQL explorer](https://cloud.hasura.io/public/graphiql) or install a tool like [GraphiQL](https://www.npmjs.com/package/graphiql) locally. ## Examples For practical query examples, see the [GraphQL API Examples](/api/graphql/examples) page. # GraphQL API Examples Source: https://docs.appsignal.com/api/graphql/examples AppSignal provides a [GraphQL API](/api/graphql) that allows you to programmatically query your application data. On this page, you'll find some examples to help you get started. Read our [GraphQL API page](/api/graphql) for more information about the GraphQL endpoint and authentication. ## Fetch deployments ### Query ```graphql GraphQL theme={null} query MarkersIndexQuery( $appId: String! $limit: Int $offset: Int $start: DateTime $end: DateTime ) { app(id: $appId) { id deployMarkers(limit: $limit, offset: $offset, start: $start, end: $end) { id createdAt shortRevision revision gitCompareUrl user liveForInWords liveFor exceptionCount exceptionRate __typename } __typename } } ``` ### Query variables ```graphql GraphQL theme={null} { "appId": "YOUR-APP-ID", "limit": 25 } ``` ## Fetch incidents by deployments ### Query ```graphql GraphQL theme={null} query ExceptionIncidentsQuery( $appId: String! $namespaces: [String] $markerId: String $limit: Int $offset: Int $state: IncidentStateEnum $order: IncidentOrderEnum ) { app(id: $appId) { id exceptionIncidents( namespaces: $namespaces marker: $markerId limit: $limit state: $state offset: $offset order: $order ) { ...ExceptionIncidentRow __typename } __typename } } fragment ExceptionIncidentRow on ExceptionIncident { id number count perMarkerCount(marker: $markerId) lastOccurredAt actionNames exceptionName state namespace firstBacktraceLine errorGroupingStrategy severity } ``` ### Query variables ```graphql GraphQL theme={null} { "appId": "YOUR-APP-ID", "markerId": "YOUR-DEPLOY-MARKER-ID", "limit": 200 } ``` ## Search incidents by tag ### Query ```graphql GraphQL theme={null} query Search( $organizationSlug: String! $query: String $namespace: String $sampleType: SampleTypeEnum ) { organization(slug: $organizationSlug) { search(query: $query, namespace: $namespace, sampleType: $sampleType) { ... on ExceptionSample { id time action namespace overview { key value } exception { name message } incident { ... on ExceptionIncident { number } } app { name environment id } } ... on PerformanceSample { id appId time action namespace duration overview { key value } incident { ... on PerformanceIncident { number } } app { name environment id } } } } } ``` ### Query variables ```graphql GraphQL theme={null} { "organizationSlug":"APPLICATION-SLUG" // taken from the URL of the application, "sampleType":"EXCEPTION", "query": "tag:value" // replace the word value with the values you are searching for } ``` ## Fetch error count ### Query ```graphql GraphQL theme={null} query MetricsListQuery( $appId: String! $start: DateTime $end: DateTime $timeframe: TimeframeEnum $query: [MetricAggregation!]! ) { app(id: $appId) { id metrics { list(start: $start, end: $end, query: $query, timeframe: $timeframe) { start end rows { name tags { key value } fields { key value } } } } } } ``` ### Query variables ```graphql GraphQL theme={null} { "appId": "YOUR-APP-ID", "start": "2021-06-04T13:00:00.000Z", // change this to the date of your preference "end": "2021-12-21T14:00:00.000Z", // change this to the date of your preference "query": [ { "name": "transaction_exception_count", "tags": [{ "key": "namespace", "value": "*" }], "fields": [{ "field": "COUNTER", "aggregate": "SUM" }] } ] } ``` ## Fetch Mean (timeseries) ### Query ```graphql GraphQL theme={null} query MetricTimeseriesQuery( $appId: String! $start: DateTime $end: DateTime $timeframe: TimeframeEnum $query: [MetricTimeseries] ) { app(id: $appId) { id metrics { timeseries( start: $start end: $end timeframe: $timeframe query: $query ) { start end resolution keys { name fields tags { key value } } points { timestamp values { value } } } } } } ``` ### Query variables ```graphql GraphQL theme={null} { "appId": "YOUR-APP-ID", "start": "2022-01-10T11:00:00Z", // Start data and time you want to fetch the Mean for "end": "2022-01-10T11:05:00Z", // End data and time you want to fetch the Mean for "query": [ { "name": "transaction_duration", "tags": [ // You can add more namespaces here, this example just fetches the Mean for web namespace. { "key": "namespace", "value": "web" } ], "fields": [ { "field": "MEAN" } ] } ] } ``` ## Fetch Mean (aggregated) ### Query ```graphql GraphQL theme={null} query MetricAggregationQuery( $appId: String! $start: DateTime $end: DateTime $timeframe: TimeframeEnum $query: [MetricAggregation!]! ) { app(id: $appId) { id metrics { list(start: $start, end: $end, timeframe: $timeframe, query: $query) { start end rows { name tags { key value } fields { key value } } } } } } ``` ### Query variables ```graphql GraphQL theme={null} { "appId": "YOUR-APP-ID", "start": "2022-01-10T11:00:00Z", // Start data and time you want to fetch the Mean for "end": "2022-01-10T11:05:00Z", // End data and time you want to fetch the Mean for "query": [ { "name": "transaction_duration", "tags": [ // You can add more namespaces here, this example just fetches the Mean for web namespace. { "key": "namespace", "value": "web" } ], "fields": [ {"field":"mean","aggregate":"AVG"} ] } ] } ``` ## Fetch incident with sample ### Query ```graphql GraphQL theme={null} query IncidentQuery( $appId: String! $incidentNumber: Int! $sampleId: String $timestamp: String $timerange: [DateTime] ) { app(id: $appId) { id incident(incidentNumber: $incidentNumber) { ... on ExceptionIncident { ...ExceptionIncident } ... on PerformanceIncident { ...PerformanceIncident } } } } fragment ExceptionIncident on ExceptionIncident { id number lastOccurredAt actionNames exceptionName notificationFrequency state namespace firstBacktraceLine errorGroupingStrategy sample(id: $sampleId, timestamp: $timestamp, timerange: $timerange) { ...ExceptionSample } } fragment ExceptionSample on ExceptionSample { id appId time revision action namespace queueDuration originallyRequested overview { key value } params sessionData customData environment { key value } exception { name message backtrace { original line column path method url type code { line source } error { class message } } } } fragment PerformanceIncident on PerformanceIncident { id number lastOccurredAt actionNames state notificationFrequency notificationThreshold namespace description severity sample(id: $sampleId, timestamp: $timestamp, timerange: $timerange) { ...PerformanceSample __typename } __typename } fragment PerformanceSample on PerformanceSample { id appId time revision action namespace originallyRequested hasNPlusOne timelineTruncatedEvents overview { key value __typename } params sessionData customData environment { key value __typename } duration queueDuration timeline { ...TimelineEvent __typename } version __typename } fragment TimelineEvent on TimelineEvent { action duration childDuration group name payload { name body __typename } time end digest count level allocationCount childAllocationCount __typename } ``` ### Query variables ```graphql GraphQL theme={null} { "appId": "YOUR-APP-ID", "incidentNumber": ID-OF-INCIDENT, "sampleId": "SAMPLE-ID-STRING", // this is optional "timestamp": "SAMPLE-TIME-STAMP", // this is optional "timerange": "SAMPLE-TIME-RANGE", // this is optional } ``` ## Fetch uptime monitors and their alerts ### Query ```graphql GraphQL theme={null} query uptimeMonitorsQuery($appId: String!) { app(id: $appId) { id uptimeMonitors { ...UptimeMonitor } } } fragment UptimeMonitor on UptimeMonitor { id name url description notifierIds warmupDuration checkBodyContent regions headers { key value } alerts { ...Alert } statusPages { ...StatusPage } } fragment Alert on Alert { id state message metricDigest createdAt openedAt resolvedAt closedAt timeframeStartAt timeframeEndAt lastValue peakValue mean tags { key value } } fragment StatusPage on StatusPage { id title subdomain hostname description threshold uptimeMonitorIds } ``` ### Query variables ```graphql GraphQL theme={null} { "appId": "YOUR-APP-ID" } ``` ## Fetch uptime monitors status ### Query ```graphql GraphQL theme={null} query MetricTimeseriesQuery( $appId: String! $start: DateTime $end: DateTime $timeframe: TimeframeEnum $query: [MetricTimeseries] ) { app(id: $appId) { id metrics { timeseries( start: $start end: $end timeframe: $timeframe query: $query ) { start end resolution keys { digest name fields tags { key value } } points { timestamp values { key value } } } } } } ``` ### Query variables ```graphql GraphQL theme={null} { "appId": "YOUR-APP-ID", "timeframe": "R1H", // Available option (R1H,R4H,R8H,R12H,,R24H,R48H, R7D,R30D) "query": [ { "name": "uptime_monitor_error_count", "tags": [ { "key": "name", "value": "NAME-OF-UPTIME-MONITOR" }, { "key": "region", "value": "*" // You can filter this to specific region as well. } ], "fields": [ { "field": "COUNTER" } ] } ] } ``` # Graphs API Source: https://docs.appsignal.com/api/graphs Endpoint \[`GET`]: | Endpoint | Description | | ------------------------------- | ------------------ | | **/api/\[app\_id]/graphs.json** | Returns graph data | Parameters: | Param | Type | Description | | ------------ | ---------------- | -------------------------------------------------------------- | | kind | string | Aggregate of provided namespace (web, background, or your own) | | action\_name | string | Example: BlogPostsController-hash-show | | from | string (ISO8601) | Defaults to 1 day ago if nil | | to | string (ISO8601) | Defaults to now if nil | | timeframe | string | Can be: \[hour, day, month, year] | | fields | array | Can be: \[mean, count, ex\_count, ex\_rate, pct] | Either provide the `action_name` or `kind` parameter. You can either specify the from an to values, **or** the timeframe value. Valid timeframes are: `hour`, `day`, `month` and `year` Valid fields are: | Field | Description | | --------- | ---------------------------------------------------- | | mean | mean response time | | count | throughput | | ex\_count | exception count | | ex\_rate | exception rate (percentage of exceptions from count) | | pct | 90 percentile (for slow requests only) | If you want an action and exception, concatenate the strings with `:|:` as a separator So `BlogPostsController#show` with `Mongoid::RecordNotFound` becomes: `BlogPostsController-hash-show:|:Mongoid::RecordNotFound"` Example request: ```shell Shell theme={null} /api/5534f7e38c5ce90000000000/graphs.json?action_name=BlogPostsController-hash-show&fields[]=mean&fields[]=pct&timeframe=month&token=aaa&from=2013-09-03T22:00:00+01:00&to=2013-10-04T00:00:00+01:00 ``` This endpoint returns a JSON object: ```json JSON theme={null} { "from": "2013-09-03T22:00:00Z", "to": "2013-10-04T00:00:00Z", "resolution": "hourly", "data": [ { "timestamp": 1378245600, "mean": 13.51942822948383, "pct": 13.213056043635918 } ] } ``` # Markers API Source: https://docs.appsignal.com/api/markers Markers are little icons used in graphs to indicate a change. This can be a deploy using a "Deploy marker" or a custom event with a "Custom marker". This Marker endpoint allows the creation and indexing of markers that are available per application. ## Marker types ### Deploy markers Deploy markers are little dots at the bottom of each graph that indicate when a new revision of an application was deployed. They’re a great way to compare deploys with each another and see if the new version increased or decreased application performance. A list of these markers is also shown on the "Deploys" page on AppSignal.com, in an Application context. For more information, also read our [deploy markers page](/application/markers/deploy-markers). ### Custom markers Custom markers provide a way to add more context to graphs, allowing you to add annotations yourself. Create a Custom marker for scaling operations, when there was a sudden spike in traffic or when a database was acting up. For more information, also read our [custom markers page](/application/markers/custom-markers). ## Marker create This endpoint enables the creation of Deploy and Custom markers. When creating the payload for this request you can select what type of marker to create by specifying the `kind` value. | | | | ------------------------ | ------------------------------ | | Endpoint | `/api/\[app_id\]/markers.json` | | Request method | POST | | Context | Applications | | Requires authentication? | Yes | | Response formats | JSON | ### Deploy marker This method of reporting deploy markers is **deprecated** and may be removed at any time in the future. Reporting deploy markers using this method is only useful for small applications that use one application instance. It creates a new deploy marker at a specific time, regardless of the version the application is actually running. This also means it's also more error prone to group data that shouldn't belong to it under the deploy. We automatically detect deployment by reading the `REVISION` file which Capistrano adds to the release directory since Ruby gem 4.5.18. | Parameter | Type | Description | | ----------- | --------------------------------------------------------- | ------------------------------------------------------------------------ | | kind | String | The kind of marker to be created - "deploy". | | created\_at | Date - [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) | Time at which to insert the marker. Leave empty to use the current time. | | repository | String | Git link or reference, e.g. "main". | | revision | String | Git revision reference. Used to create git diff links in the UI. | | user | String | User that has initiated the deploy. | #### Payload example ```json JSON theme={null} { "marker": { "kind": "deploy", "created_at": "2015-07-21T15:06:31.737+02:00", "repository": "git@github.com:company/repository.git", "revision": "fe001015311af4769a4dad76bdbce4c8f5d022af", "user": "user" } } ``` #### Payload example with curl ```bash Bash theme={null} curl -H "Content-Type: application/json" -XPOST https://appsignal.com/api/[app-id]/markers.json?token=[your-personal-token] \ -d '{ "marker":{ "kind": "deploy", "repository": "git@github.com:company/repository.git", "revision": "[revision]", "user": "[user]"}}' ``` All requests to AppSignal API endpoints require a personal API token given as an URL query parameter for [authentication](/api#authentication). ### Custom marker Used to annotate events that can impact your performance/error rate. Examples are: up/downscale of cloud infrastructure, maintenance on database, cause of error spikes. If you want to create custom markers, but not use your Personal API token, you can use the [public endpoint](/api/public-endpoint/custom-markers) instead. | Parameter | Type | Description | | ----------- | --------------------------------------------------------- | ----------------------------------------------------------------------------------- | | kind | String | The kind of marker to be created - "custom". | | created\_at | Date - [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) | Time at which to insert the marker. Leave empty to use the current time. | | icon | String - Optional | Emoji to use for this Custom marker, defaults to πŸš€. | | message | String - Optional | Message shown when hovering over the marker in the UI. Truncated to 200 characters. | #### Payload example ```json JSON theme={null} { "marker": { "kind": "custom", "created_at": "2015-07-21T15:06:31.737+02:00", "icon": "πŸ’©", "message": "Accidentlly dropped production DB" } } ``` ## Marker index This endpoint returns a list of markers. Combines both Deploy and Custom markers. | | | | ------------------------ | ------------------------------ | | Endpoint | `/api/\[app_id\]/markers.json` | | Request method | `GET` | | Context | Applications | | Requires authentication? | Yes | | Response formats | JSON | ### Parameters | Parameter | Type | Description | | ----------- | ------------------------------------------------------------------------------------ | -------------------------------------------------------------- | | kind | String | The kind of marker to be created - "custom". | | from | Date - [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) / Integer - UNIX timestamp | All times are UTC. | | to | Date - [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) / Integer - UNIX timestamp | All times are UTC. | | limit | Integer | Limit the number of markers returned. | | count\_only | Boolean | Set to "true" to only return the number of markers that exist. | ### Response ```json JSON theme={null} { "count": 4212, "markers": [ { "kind": "deploy", "id": "50a61f1b660cd3677775ccb0", "created_at": "2015-07-21T15:06:31.737+02:00", "closed_at": null, "live_for": 107413, "live_for_in_words": "1d", "gem_version": null, "repository": "git@github.com:company/repository.git", "revision": "fe001015311af4769a4dad76bdbce4c8f5d022af", "short_revision": "fe00101", "git_compare_url": "https://github.com/company/repository/compare/aaa...bbb", "user": "user", "exception_count": 200, "exception_rate": 8.81 }, { "kind": "custom", "icon": "πŸ’©", "message": "Accidentlly dropped production DB", "created_at": "2015-07-21T15:06:31.737+02:00" }, { "kind": "notification", "message": "Appsignal API issues.", "created_at": "2015-07-21T15:06:31.737+02:00" } ] } ``` With `"count_only": true`. ```json JSON theme={null} { "count": 4212 } ``` ## Marker show This endpoint returns the JSON representation of a single marker. | | | | ------------------------ | -------------------------------------------- | | Endpoint | `/api/\[app_id\]/markers/\[marker_id\].json` | | Request method | `GET` | | Context | Applications | | Requires authentication? | Yes | | Response formats | JSON | ### Parameters | Parameter | Type | Description | | ---------- | ------ | ------------------------------- | | marker\_id | String | The id of the marker to return. | ### Response The response for Deploy markers and Custom markers is different. Deploy markers contain more data about a certain deploy while Custom markers only contain the data given on creation. #### Deploy marker ```json JSON theme={null} { "id": "50a61f1b660cd3677775ccb0", "created_at": "2015-07-21T15:06:31.737+02:00", "closed_at": null, "live_for": 107413, "live_for_in_words": "1d", "gem_version": null, "repository": "git@github.com:company/repository.git", "revision": "fe001015311af4769a4dad76bdbce4c8f5d022af", "short_revision": "fe00101", "git_compare_url": "https://github.com/company/repository/compare/aaa...bbb", "user": "user", "exception_count": 200, "exception_rate": 8.81 } ``` #### Custom marker ```json JSON theme={null} { "kind": "custom", "icon": "πŸ’©", "message": "Accidentlly dropped production DB", "created_at": "2015-07-21T15:06:31.737+02:00" } ``` #### Notification marker ```json JSON theme={null} { "kind": "notification", "message": "Appsignal API issues.", "created_at": "2015-07-21T15:06:31.737+02:00" } ``` ## Marker update This endpoint updates a single marker and returns the JSON representation of the updated marker. | | | | ------------------------ | -------------------------------------------- | | Endpoint | `/api/\[app_id\]/markers/\[marker_id\].json` | | Request method | PUT | | Context | Applications | | Requires authentication? | Yes | | Response formats | JSON | ### Parameters | Parameter | Type | Description | | ---------- | ------ | ------------------------------- | | marker\_id | String | The id of the marker to update. | ### Payload The payload is the same as a [create/POST](#marker-create) request and differs per marker type. ### Response The response is the same as a [show/GET](#marker-show) request and differs per marker type. ## Marker delete This endpoint deletes a single marker. | | | | ------------------------ | -------------------------------------------- | | Endpoint | `/api/\[app_id\]/markers/\[marker_id\].json` | | Request method | DELETE | | Context | Applications | | Requires authentication? | Yes | | Response formats | JSON | ### Parameters | Parameter | Type | Description | | ---------- | ------ | ------------------------------- | | marker\_id | String | The id of the marker to delete. | ### Response The response body of this request is empty. The status code will return if it was successful or not. # Public endpoint Source: https://docs.appsignal.com/api/public-endpoint This API is a traffic-optimized endpoint to push data to AppSignal that is not sent through the [AppSignal agent](/appsignal/how-appsignal-operates#agent). ## Base URL ```shell Shell theme={null} https://appsignal-endpoint.net ``` ## Authentication Authentication is done with a Public endpoint (or Front-end) API key, which can be found in [App settings](https://appsignal.com/redirect-to/app?to=info). ## URL Parameters | Parameters | Type | Description | | ---------- | ------ | ----------------------------------------------------------------------------------------------------- | | api\_key | String | **Front-end** API key, can be found in [App settings](https://appsignal.com/redirect-to/app?to=info). | Full example: ```shell Shell theme={null} https://appsignal-endpoint.net/metrics/statsd?api_key= ``` **Note**: This endpoint is optimized for large amounts of traffic and does not validate the API key or payload, a `200` (`OK`) response is returned when the body size is within the `200k` limit. This doesn't mean the request is accepted when received. ## Endpoints This API exposes the following endpoints: * [StatsD Metrics](/api/public-endpoint/statsd) Send (batched) StatsD-formatted metrics to AppSignal. * [JSON Metrics](/api/public-endpoint/json-metrics) Send (batched) JSON-formatted metrics to AppSignal. * [Errors](/api/public-endpoint/errors) Send Errors to AppSignal. # Public Endpoint - Custom Markers Source: https://docs.appsignal.com/api/public-endpoint/custom-markers This endpoint is an alternative to our [markers api endpoint](/api/markers#custom-marker) endpoint, and uses a different authentication method. ## Endpoint Request method: `POST` | Endpoint | Description | | -------------------------------------------------------------------------------- | --------------------------- | | [https://appsignal-endpoint.net/markers](https://appsignal-endpoint.net/markers) | Accepts JSON formatted data | ## URL parameters Depending on the API key you'd like to use, you can either: ### Push API key | Parameter | Type | Description | | ----------- | ------ | ------------------------------------------------------------------------------------------------ | | api\_key | String | **Push** API key, can be found in [App settings](https://appsignal.com/redirect-to/app?to=info). | | name | String | The application name. | | environment | String | The environment that the application is running in. | ```shell Shell theme={null} https://appsignal-endpoint.net/markers?api_key=&name=&environment= ``` ### Front-end API key | Parameter | Type | Description | | --------- | ------ | ----------------------------------------------------------------------------------------------------- | | api\_key | String | **Front-end** API key, can be found in [App settings](https://appsignal.com/redirect-to/app?to=info). | ```shell Shell theme={null} https://appsignal-endpoint.net/markers?api_key= ``` ## Body parameters The post body should contain a JSON object, formatted as follows: | Parameter | Type | Description | | ----------- | --------------------------------------------------------- | ----------------------------------------------------------------------------------- | | created\_at | Date - [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) | Time at which to insert the marker. Leave empty to use the current time. | | icon | String - Optional | Emoji to use for this Custom marker, defaults to πŸš€. | | message | String - Optional | Message shown when hovering over the marker in the UI. Truncated to 200 characters. | For example: ```json JSON theme={null} { "created_at": "2015-07-21T15:06:31.737+02:00", "icon": "πŸš€", "message": "Upscaled the database for better performance" } ``` # Public Endpoint - Errors Source: https://docs.appsignal.com/api/public-endpoint/errors This Error API endpoint is provided to add additional errors to AppSignal, where an existing integration can't be used or the language used isn't supported (yet). ## Endpoint Request method: `POST` | Endpoint | Description | | ------------------------------------------------------------------------------ | --------------------------- | | [https://appsignal-endpoint.net/errors](https://appsignal-endpoint.net/errors) | Accepts JSON formatted data | ## URL parameters | Parameter | Type | Description | | --------- | ------ | ----------------------------------------------------------------------------------------------------- | | api\_key | String | **Front-end** API key, can be found in [App settings](https://appsignal.com/redirect-to/app?to=info). | ```shell Shell theme={null} https://appsignal-endpoint.net/errors?api_key= ``` ## Body parameters The post body should contain a JSON object, formatted as follows: | Parameter | Type | Description | | ----------- | ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------- | | timestamp | Integer | (Epoch) timestamp when error occurred | | action | String | (Optional) Action name where error occurred (e.g. `BlogpostController#show` or `UserInfoLambda#perform`) | | namespace | String | Namespace where error occurred (e.g. `frontend` or `lambda` ) | | error | Error | Error object, see description below | | revision | String | (Optional) Full (GIT) revision hash of application | | tags | `Object` | (Optional) Tags to filter the sample on, or to provide additional context. Make sure both key and values are strings (e.g. `{"account_id": "abc-123"}`) | | params | `Object` | (Optional) Parameters that were given to the function where the error occurred. Make sure both key and values are strings (e.g. `{"id": "abc-123"}`) | | environment | `Object` | (Optional) Environment values that were set when the error occurred. Make sure both keys and values are strings (e.g. `{"REGION": "eu-central-1"}`) | | breadcrumbs | `Array` | (Optional) Array of breadcrumbs, recorded before the error occurred. See below for description of Breadcrumb object | | language | String | (Optional) Language string, used to format the backtrace. Accepted values are `ruby`, `javascript`. Leave empty when using another language | Error: | Parameter | Type | Description | | --------- | --------------- | ----------------------------------------------------------------- | | name | String | Error name (e.g. `StandardError`) | | message | String | (Optional) Error message | | backtrace | `Array` | (Optional) Array of backtrace lines, each line should be a string | Breadcrumb: | Parameter | Type | Description | | --------- | ------------------------ | ------------------------------------------------------------------ | | category | String | Category to label the event under (e.g. `network` or `navigation`) | | action | String | Contextual information related to the event | | message | String | (optional) A log message or other string to send to AppSignal | | metadata | `Object` | (optional) An object of metadata related to the event | For example: ```json JSON theme={null} { "action": "BlogpostController#show", "namespace": "frontend", "timestamp": 1559201249, "error": { "name": "StandardError", "message": "Error message", "backtrace": ["backtrace/line:1", "backtrace/line:2"] }, "environment": { "os": "windows", "agent": "super secret user agent" }, "params": { "foo": "bar" }, "tags": { "account_id": "abc-123" }, "revision": "revision-abc", "breadcrumbs": [ { "timestamp": 1559201249, "category": "request", "action": "http://google.com", "message": "request failed", "metadata": { "code": "not_found" } } ], "language": "javascript" } ``` ## Example ```ruby Ruby theme={null} require "uri" require "json" require "net/http" url = URI("https://appsignal-endpoint.net/errors?api_key=FRONTEND-API-KEY") https = Net::HTTP.new(url.host, url.port) https.use_ssl = true request = Net::HTTP::Post.new(url) request["Content-Type"] = "application/json" request.body = JSON.dump({ "action": "BlogpostController#show", "namespace": "frontend", "timestamp": 1640327525, "error": { "name": "StandardError", "message": "Error message", "backtrace": [ "backtrace/line:1", "backtrace/line:2" ] }, "environment": { "os": "windows", "agent": "super secret user agent" }, "params": { "foo": "bar" }, "tags": { "account_id": "abc-123" }, "revision": "revision-abc-123", "breadcrumbs": [ { "timestamp": 1640327525, "category": "request", "action": "http://google.com", "message": "request failed", "metadata": { "code": "not_found" } } ], "language": "javascript" }) response = https.request(request) puts response.read_body ``` **Note**: This endpoint is optimized for large amounts of traffic and does not validate the API key or payload, a `200` (`OK`) response is returned when the body size is within the `200k` limit. This doesn't mean the request is accepted when received. # Public Endpoint - JSON Metrics Source: https://docs.appsignal.com/api/public-endpoint/json-metrics This API endpoint is provided to add additional metrics to AppSignal, where an existing integration can't be used or the language used isn't supported (yet). This endpoint is meant for integrations that send aggregated metrics over a small period, it's preferred to send one request every 5 seconds with 100 metrics over 100 requests per 5 minutes with one metric each. ## Endpoint Request method: `POST` | Endpoint | Description | | ------------------------------------------------------------------------------------------ | --------------------------- | | [https://appsignal-endpoint.net/metrics/json](https://appsignal-endpoint.net/metrics/json) | Accepts JSON formatted data | ## URL parameters | Parameter | Type | Description | | --------- | ------ | ----------------------------------------------------------------------------------------------------- | | api\_key | String | **Front-end** API key, can be found in [App settings](https://appsignal.com/redirect-to/app?to=info). | ```shell Shell theme={null} https://appsignal-endpoint.net/metrics/json?api_key= ``` ## Body parameters The post body should contain JSON formatted metrics separated by a newline, or as a full json body. | Parameter | Type | Description | | ---------- | ------------------------ | --------------------------------------------------------------------------------------------------------- | | name | String | Name of metric, shouldn't contain spaces or special characters, e.g. only (`[a-zA-Z0-9-_]`) | | metricType | String | Metric type, can be one of `[gauge, counter, timing, histogram]` | | value | Float | (Float) value | | tags | `Object` | Object containing tags. Both key and value should be a string, for example: `{ "hostname": "frontend1" }` | Example of JSON body ```json JSON theme={null} [ { "name": "traffic_gauge", "metricType": "gauge", "value": 19.8, "tags": { "hostname": "frontend1" } }, { "name": "error_counter", "metricType": "counter", "value": 10, "tags": { "hostname": "frontend1", "disk": "vda" } }, { "name": "duration_timing", "metricType": "timing", "value": 19, "tags": { "lambda": "login" } }, { "name": "duration_timing", "metricType": "histogram", "value": 5, "tags": { "lambda": "login" } } ] ``` Example of newline-separated body: ```json JSON theme={null} {"name": "traffic_gauge", "metricType": "gauge", "value": 19.8, "tags": {"hostname": "frontend1"}}\n {"name": "error_counter", "metricType": "counter", "value": 10, "tags": {"hostname": "frontend1", "disk": "vda"}}\n {"name": "duration_timing", "metricType": "timing", "value": 19, "tags": {"lambda": "login"}}\n {"name": "duration_timing", "metricType": "histogram", "value": 5, "tags": {"lambda": "login"}}\n ``` **Note**: This endpoint is optimized for large amounts of traffic and does not validate the API key or payload, a `200` (`OK`) response is returned when the body size is within the `200k` limit. This doesn't mean the request is accepted when received. # Public Endpoint - StatsD Metrics Source: https://docs.appsignal.com/api/public-endpoint/statsd This StatsD API endpoint is provided to add additional metrics to AppSignal, where an existing integration can't be used or the language used isn't supported (yet). This endpoint is meant for integrations that send aggregated metrics over a small period, it's preferred to send one request every 5 seconds with 100 metrics than 100 requests per 5 minutes with one metric each. ## Endpoint Request method: `POST` | Endpoint | Description | | ---------------------------------------------------------------------------------------------- | ------------------------ | | [https://appsignal-endpoint.net/metrics/statsd](https://appsignal-endpoint.net/metrics/statsd) | Accepts (Dog)StatsD data | ## URL parameters | Parameter | Type | Description | | --------- | ------ | ----------------------------------------------------------------------------------------------------- | | api\_key | String | **Front-end** API key, can be found in [App settings](https://appsignal.com/redirect-to/app?to=info). | ```shell Shell theme={null} https://appsignal-endpoint.net/metrics/statsd?api_key= ``` ## Body parameters The post body should contain (Dog)StatsD formatted metrics separated by a newline. For example: ```shell Shell theme={null} login_count:1|c|#hostname:frontend1 stripe_api_duration:19|ms|#function:payment,domain:appsignal cpu_usage:55.1|g|#hostname:frontend1,cpu:0 ``` Here is a complete example on how to send these metrics using `cURL`. (Note the use of single quotes for the `--data` option and the leading `$`. Only then will line breaks work in the `--data` value.) ```shell Shell theme={null} curl -H "Content-Type: text/plain" -X POST --data $'login_count:10|c|#hostname:frontend1\nstripe_api_duration:19|ms|#function:payment,domain:appsignal' "https://appsignal-endpoint.net/metrics/statsd?api_key=FRONTEND-API-KEY" ``` **Note**: This endpoint is optimized for large amounts of traffic and does not validate the API key or payload, a `200` (`OK`) response is returned when the body size is within the `200k` limit. This doesn't mean the request is accepted when received. # Samples API Source: https://docs.appsignal.com/api/samples ## Samples index Endpoints \[`GET`]: | Endpoint | Description | | ---------------------------------------- | ------------------------------------ | | `/api/[app_id]/samples.json` | This returns **ALL** sample types | | `/api/[app_id]/samples/performance.json` | This returns **performance** samples | | `/api/[app_id]/samples/errors.json` | This returns **error** samples | Parameters: | Param | Type | Description | | ----------- | ----------------- | ----------------------------------------------: | | action\_id | string | Example: `BlogPostsController-hash-show` | | exception | string | Example: NoMethodError | | since | timestamp/integer | All times are UTC | | before | timestamp/integer | All times are UTC | | limit | integer | The amount of entries returned (defaults to 10) | | count\_only | boolean | (true/false) To only return a count | Escape actions by replacing: * `#` with `-hash-` * `/` with `-slash-` * `.` with `-dot-` So `BlogPostsController#show` becomes: `BlogPostsController-hash-show` An example of a full request would be: ```shell Shell theme={null} https://appsignal.com/api/5114f7e38c5ce90000000011/samples.json?token=HseUe&action_id=AccountsController-hash-index&exception=ActionView::Template::Error&since=1374843246 ``` ### Result This endpoint returns the following JSON (a slow sample and an error sample): ```json JSON theme={null} { "count": 2, "log_entries": [ { "id": "51f29e7b183d700800150358_SlowController#show_1476962400", "action": "SlowController#show", "path": "/slow-request", "duration": 3182.545407, "status": 200, "time": 1476962400, "is_exception": false, "exception": { "name": null } }, { "id": "57f653fa16b7e24cb0dc9e2b_ErrorController#trigger_1475761080", "action": "ErrorController#trigger", "path": "/error-request", "duration": null, "status": null, "time": 1475761080, "is_exception": true, "exception": { "name": "ActionView::Template::Error" } } ] } ``` ## Samples show Endpoint \[`GET`]: `/api/[app_id]/samples/[id].json` Parameters: | Param | Type | Description | | ----- | ------ | --------------------------------------------------------------------------------------------: | | id | string | Sanitized sample id (example: `51f29e7b183d700800150358_SlowController-hash-show_1476962400`) | ### Result This is a **SLOW** log entry: ```json JSON theme={null} { "id": "51f29e7b183d700800150358_SlowController#show_1476962400", "action": "slow#request", "db_runtime": 500.0, "duration": 300.0, "environment": {}, "hostname": "app1", "is_exception": null, "kind": "http_request", "params": {}, "path": "/blog", "request_format": "html", "request_method": "GET", "session_data": {}, "status": "200", "view_runtime": 500.0, "time": 1002700800, "end": 978339601, "allocation_count": 110101, "events": [ { "action": "query", "duration": 250.0, "group": "mongoid", "name": "query.mongoid", "payload": { "query": "this is a mongoid query" }, "time": 0, "end": 0 "digest": 00000, "allocation_count": 1010101 } ], "exception": null } ``` This is an **ERROR** log entry: ```json JSON theme={null} { "id": "57f653fa16b7e24cb0dc9e2b_ErrorController#trigger_1475761080", "action": "Error#trigger", "db_runtime": 500.0, "duration": null, "environment": { "HTTP_USER_AGENT": "Mozilla/5.0 (Macintosh" }, "hostname": "app1", "is_exception": true, "kind": "http_request", "params": { "id": 1, "get": "something" }, "path": "/blog", "request_format": "html", "request_method": "GET", "session_data": { "current_user_id": 1 }, "status": "200", "view_runtime": 500.0, "time": 1002700800, "end": 978339601, "events": [], "tags": { "user": "john doe", "id": 1 }, "exception": { "message": "The method was not found", "name": "NoMethodError", "backtrace": ["Backtrace line 1", "Backtrace line 2", "Backtrace line 3"] } } ``` **Note:** If you need more advanced querying, such as searching samples by tag, you can do that using our [GraphQL API](https://docs.appsignal.com/api/graphql). Check out the GraphQL API docs for query examples and more details. # Sourcemaps API Source: https://docs.appsignal.com/api/sourcemaps Sourcemaps are used to get the original line and column number from a backtrace pointing to a minified or transpiled file. We recommend using [public sourcemaps](/front-end/sourcemaps#public-sourcemaps) whenever possible. Builds that produce lots of sourcemaps can take a long time to upload via our private sourcemap endpoint. This API provides an easy way to upload private sourcemaps for use with [frontend errors](/front-end/sourcemaps). Private sourcemaps will not be used to resolve Node.js backtraces. Follow the [Node.js installation instructions](/nodejs/3.x/installation#typescript-support) to configure your application to emit sourcemapped backtraces. ## Create sourcemap This endpoint enables the creation of private sourcemaps. | | | | ------------------------ | --------------------------------------------------------- | | Endpoint | `/api/sourcemaps` | | Request method | `POST` | | Content-Type | `multipart/form-data` | | Requires authentication? | Yes ([Push API key](/appsignal/terminology#push-api-key)) | | Response formats | JSON | ### Matching sourcemaps We will match the values for the `name[]` fields against the full backtrace URL. For example, the following backtrace line: ```shell Shell theme={null} at https://test.local/main.abc123.js:1:92623 ``` Will match with the `name`: `https://test.local/main.abc123.js`. You can add multiple `name`'s in one curl request: ```bash Bash theme={null} curl -k -X POST -H 'Content-Type: multipart/form-data' \ -F 'name[]=https://test.local/main.abc123.js' \ -F 'name[]=https://cdn.local/main.abc123.js' \ -F 'revision=abcdef' \ -F 'file=@/~project/main.js.map' \ 'https://appsignal.com/api/sourcemaps?push_api_key=xxx&app_name=AppSignal&environment=development' ``` Note that you can only upload one sourcemap file at a time, so if you have multiple sourcemap files, you will have to send an upload request for each file separately. The maximum upload size allowed for a sourcemap file is 100MB. ### Parameters All parameters, except for `file` can be sent either in the `POST` body or as `GET` parameters. All parameters are **required**. | Parameter | Type | Description | | -------------- | ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `push_api_key` | String | Your organization's [Push API key](/appsignal/terminology#push-api-key). | | `app_name` | String | Name of the application in AppSignal in which the sourcemap should be used. | | `environment` | String | Environment of the application in AppSignal in which the sourcemap should be used. | | `revision` | String | [Deploy marker](/application/markers/deploy-markers) revision reference. | | `name` | Array of Strings | List of filenames that the sourcemap covers. This should be a full URL to the minified JavaScript file, as you see it in the backtrace, including any url params. | | `file` | File | Sourcemap to upload. | ### Responses * The API will return a `201` HTTP status code if successful. * The API will return a `400` HTTP status code with a JSON response when a validation error has occurred. * The API will return a `404` HTTP status code if no app exists for the given app name, environment and Push API key combination. 400 response body example: ```json JSON theme={null} { "errors": ["The following errors were found: Name can't be empty"] } ``` ### Example ```bash Bash theme={null} curl -k -X POST -H 'Content-Type: multipart/form-data' \ -F 'name[]=https://localhost:3000/application.min.js?vsn=d ' \ -F 'revision=abcdef' \ -F 'file=@/~project/application.js.map' \ 'https://appsignal.com/api/sourcemaps?push_api_key=xxx&app_name=MyApp&environment=development' ``` # Applications Source: https://docs.appsignal.com/application Applications (previously known as "sites", also referred to as "apps") are Ruby, Elixir and JavaScript front-end applications monitored by AppSignal. Every application is unique by the combination of its name and environment. A list of Applications appears on the [Application index] and in the application quick switcher. Every application has a parent [organization](/organization), which can have multiple applications. (Exception: Organizations created by the Heroku add-on only support one application.) ## Adding applications If you're just getting started with AppSignal and haven't set up your first app yet, please follow the [add a new application guide](/guides/new-application) first. πŸ“– Read our [add a new application guide](/guides/new-application). ## Environments An application can have multiple [environments](/appsignal/terminology#environments) as long as every environment uses the same application name. Every environment is currently listed separately on the [Application index]. * "Demo application" - development * "Demo application" - production * "Demo application" - staging * "Demo application" - test ## Namespaces Namespaces are a way to group error incidents, performance incidents from [actions](/appsignal/terminology#actions), and host metrics in your app. By default AppSignal provides three namespaces: the "web", "background" and "frontend" namespaces. You can add your own namespaces to separate parts of your app like the API or Admin panel. Namespaces can be used to group together incidents that are related to the same part of an application. It's also possible to configure notification settings on a per-namespace level. Read more about [namespaces](/application/namespaces) and how to configure them for your app. ## See also * [πŸ“– Removing an application guide](/guides/application/deleting-applications) * [πŸ“– Migrating an application between organizations guide](/guides/application/migrating-applications) * [πŸ“– Running multiple applications on one host](/guides/application/multiple-applications-on-one-host) [application index]: https://appsignal.com/accounts # Backtrace links Source: https://docs.appsignal.com/application/backtrace-links With backtrace links you can spend less time figuring out where an exception happened and more time debugging the exception. Backtrace links make every line to source code in your app link to your app's source code on your source code hosting platform of choice. Backtrace with Git link ## Steps to enable backtrace links To enable backtrace links an app on AppSignal.com needs to: 1. [Enable deploy markers](/application/markers/deploy-markers). * This will allow AppSignal to link to the specific revision of the source code in which the error occurred. 2. Configure the "repo url" for an application, or [link your organization to GitHub](https://appsignal.com/redirect-to/organization?to=admin/integrations/github), so AppSignal knows where to link to. * See the steps below for either option. ## Configure the repo url Owners of an Organization can specify a Repo url on [the app settings page](https://appsignal.com/redirect-to/app?to=edit). This is especially useful for Git hosting platforms that are not GitHub (e.g. GitLab/BitBucket) or private repositories. App settings repo URL form ## Link your app to GitHub Alternatively organization owners can [link an app to GitHub](https://appsignal.com/redirect-to/app?to=integrations) and the "repo url" from the selected repository will be stored automatically. With the GitHub integration you'll also be able to send incidents to GitHub directly from AppSignal. Once the steps are completed we'll automatically enrich the backtrace lines with a link to the correct revision/file/line on the specified Git repository. ## Send error to GitHub When an error occurs, AppSignal will not create an issue automatically on GitHub, if you think it is an error that needs to be fixed then you can create this error as an issue in GitHub by clicking on the "Send to GitHub" button. Send error to github ## Open backtrace lines in your local editor Once configured, each app code line in an exception backtrace gets an **Open in editor** button that opens the file directly in your local editor. Before setup, the option is available in the extras menu, accessible via the there dots icon. ### Setup Go to **App Settings β†’ Editor preferences**, select your editor, and enter the absolute path to the project on your local machine. These settings are personal β€” each developer on your team configures their own. Supported editors: **VS Code**, **Cursor**, **Windsurf**, **Zed**, **RubyMine**, and **Sublime Text**. # Configuration Source: https://docs.appsignal.com/application/configuration Configuration. Important, because without it the AppSignal integrations won't know which application it's instrumenting or in which environment. In this section we'll explain how configuration works in AppSignal integrations, what options can be configured in the integrations, what the minimal configuration needed is and in what order the configuration is loaded. πŸ“– Want a more practical read on how to add or change AppSignal configuration? Read our [guide on how to configure AppSignal][guide] in your apps. ## Minimal required configuration Every app needs to have four key configuration options set for AppSignal to report data for it. These config options help AppSignal identify an app, and group all the data for it in an app environment on AppSignal.com. Every app is a combination of the app name and environment, in AppSignal terminology this is an "app". These required configuration options are: * App name * The app name as it is reported and shown on AppSignal.com * App environment * The app environment as it is reported and shown on AppSignal.com * [Push API key] * The key used to identify which organization the app belongs to or which app is reporting data. Read more about the [Push API key] on our terminology page. * AppSignal active * The config option used to enable, or disable, environments on the host's config. This allows users to disable development and test environments, and only report data for the production and staging environment, for example. The detailed list of required options per integration can be found in the [configuration options section](#configuration-options). Find the list of required configuration options at the top of each config options page. For Front-end JavaScript all required options are combined in a [`key` config option][frontend config], and the app name and environment are configured on AppSignal.com during the "add app" wizard. Some of these configuration options may be set to a default value by the integrations, such as the app name for Rails apps, and environment for Elixir and Node.js apps. ## Configuration options Every integration has its own set of configuration options. There's a list of shared options and options specific to each integration. The full list of configuration options can be found in the language integration sections: * [Ruby](/ruby/configuration/options) * [Elixir](/elixir/configuration/options) * [Node.js](/nodejs/3.x/configuration/options) * [Python](/python/configuration/options) * [Front-end Javascript](/front-end/configuration/) * [Go](/go/configuration/options) ## Configuration methods There are two main ways to configure AppSignal integrations, by (configuration) file or by system environment variables. Use the configuration method that best fits your app setup. Read our [guide on how to configure AppSignal][guide] in your app. ## Configuration load order Depending on the integration the load order of the configuration may differ, please consult the load order page for the integrations for more information: * [Ruby configuration load order](/ruby/configuration/load-order) * [Elixir configuration load order](/elixir/configuration/load-order) * [Node.js configuration load order](/nodejs/3.x/configuration/load-order) * [Python configuration load order](/python/configuration/load-order) *If a language is not listed, it has no different configuration sources to load configuration options from.* ## See also * [AppSignal configuration guide][guide] * AppSignal integration configuration topics: * [Ruby configuration topic](/ruby/configuration) * [Elixir configuration topic](/elixir/configuration) * [Node.js configuration topic](/nodejs/3.x/configuration) * [Python configuration topic](/python/configuration) * [Front-end JavaScript configuration topic][frontend config] * [Go configuration topic](/go/configuration) [guide]: /guides/configuration.html [Push API key]: /appsignal/terminology.html#push-api-key [frontend config]: /front-end/configuration.html # Customizing data collection Source: https://docs.appsignal.com/application/data-collection By default AppSignal gathers relevant data for errors and performance measurements to help you find the cause of the issue. Sometimes you need more information, app specific data or a custom request header your app uses. You can configure AppSignal to gather more, or less, information than it does by default by tagging your transactions and configuring the request headers, parameter filtering, etc. Ideally we receive as little metadata for samples as possible, and only data that is needed to debug an exception or performance issue. πŸ“– Read our [filtering app data guide](/guides/filter-data/) about limiting what (sensitive) data is collected by AppSignal. It will guide you through configuring which parameters, session data and request headers to collect. ## Ignore actions By configuring the `ignore_actions` option it's possible to not record any data for the configured actions, requests, background jobs, etc. πŸ“– Read our [guide about ignoring actions](/guides/filter-data/ignore-actions). ## Ignore errors By configuring the `ignore_errors` option it's possible to ignore errors matching the exact name of an error for the entire app. πŸ“– Read our [guide about ignoring errors](/guides/filter-data/ignore-errors). ## Namespaces Namespaces allow grouping of [actions](/appsignal/terminology#actions). By default AppSignal uses the "web", "background" and "frontend" namespaces to group [transactions](/appsignal/terminology#transactions). It's possible to create a custom namespace such as "admin", "api" to group controllers in the same namespace. The grouped actions in the namespace can be configured with their own notification defaults, allowing a critical namespace to always notify about errors, while the "web" namespace does not. It's also possible to configure the AppSignal integration to ignore a namespace to ignore all transactional data from all actions in it. Read more about namespaces in the [namespaces section](/application/namespaces). ## Tagging Our tagging system allows you to attach more metadata to samples, besides what we already collect. Things such as the ID of the user making the request or other data that can help you identify who made the request or specific conditions for the request. ## Queries By default we parse SQL queries and try and remove any parameters in the query string. We've created an open-source (Rust) package that is used by our integrations. You can find [the sql\_lexer project on GitHub](https://github.com/appsignal/sql_lexer). If you see any query params in our UI, please open an issue in that repository. MongoDB queries in the Ruby integration are sanitized by default. # Environment metadata Source: https://docs.appsignal.com/application/environment-metadata The AppSignal integrations and agent collect metadata about the host and app it is integrating with. The specifics about which metadata is collected is listed below. This metadata is used to: * enrich the data available on AppSignal.com (to provide a more complete picture of the host and app), * provide additional information for debugging purposes as a supplement to the diagnose command, * product improvement as part of an anonymous aggregated dataset. To disable this feature, set the `send_environment_metadata` config option to `false`: * [Ruby](/ruby/configuration/options#option-send_environment_metadata) * [Elixir](/elixir/configuration/options#option-send_environment_metadata) * [Node.js](/nodejs/3.x/configuration/options#option-send_environment_metadata) * [Python](/python/configuration/options#option-send_environment_metadata) ## AppSignal metadata * AppSignal integration version * What package and version of AppSignal is installed. This is either the Ruby gem, Elixir package or the Node.js package. * AppSignal agent version * What version of the AppSignal agent is installed. This is used to recognize the version when [standalone mode] is used. * Agent release * Reports which architecture was installed, 32 or 64-bit. The AppSignal extension and agent are built for each architecture separately. * Reports whether the [musl build](/support/operating-systems#supported-versions) was installed. * Agent standalone mode enabled * If the agent is running in [standalone mode]. This is used for hosts that run systems such as databases, that still want to report host metrics for it. * Agent StatsD mode enabled * If the agent has [StatsD mode] enabled. * Optional enabled features * AppSignal integrations have some optional features that can be enabled, usually prefixed with the `enable_` name in the config options. It is reported only when they are enabled. ## App metadata * Integration language * What the integration language is (Ruby/Elixir/Node.js) and what version. * Integration language implementation * What the language implementation is, if any (MRI or JRuby), and what version. * Integration supported libraries * A list of which AppSignal supported libraries integrations are loaded and what version, e.g. Rails, Phoenix, Express. Only information of officially supported AppSignal packages is sent, but not any unsupported or private packages. ## Host metadata The host data is available for hosts in the [host metrics] feature, adding details to hosts in the overview. * Architecture * Whether the system is 32 or 64-bit architecture. * Operating System * Operating System, either Linux, macOS or Windows. * Operating System Distribution, for Linux this reports Ubuntu, Fedora, etc. * Operating System version, the version of the Operating System. * Kernel version, for Linux this reports the installed kernel version. * Containerized system * Is the host part of a container system such as Docker. On container system such as Docker the AppSignal agent is using a different method with which host metrics are reported. * Platform * If Heroku is detected as platform. Our integrations and agent use different settings on Heroku. [standalone mode]: /standalone-agent/installation.html [statsd mode]: /standalone-agent/statsd.html [host metrics]: /metrics/host-metrics.html # Request header collection Source: https://docs.appsignal.com/application/header-filtering AppSignal collects headers for HTTP requests by default for supported frameworks. This data may help track down errors or performance issues that were caused by requests header data a client is sending. To comply with [GDPR](/appsignal/gdpr) rules, collecting no user identifiable data, AppSignal collects a very limited amount of headers by default. To even further limit the request headers or collect more than the default list of headers, configure AppSignal which headers to collect. πŸ” Do not send Personal Identifiable Information (PII) to AppSignal. Filter PII (e.g., names, emails) and use an ID, hash, or pseudonymized identifier instead.

For HIPAA-covered entities, more info on signing a Business Associate Agreement (BAA) is available in our Business Add-Ons documentation.
## Configure headers An app's session data can be filtered by configuring keys in an *allowlist*. This allowlist system will filter out all the session data keys not in this list. All headers that are filtered out by these systems are not collected, neither the header name or value. πŸ“– Read our guide about [setting up request header collection and filtering](/guides/filter-data/filter-headers) for your app. ## Filter all request headers To filter all request headers without individual header filtering, configure the allowlist to an empty list in the integration configuration. Without any header names in the list, it will not collect any request headers. * [Ruby `request_headers` config option documentation](/ruby/configuration/options#option-request_headers) * [Elixir `request_headers` config option documentation](/elixir/configuration/options#option-request_headers) * [Node.js `requestHeaders` config option documentation](/nodejs/3.x/configuration/options#option-requestheaders) * [Python `request_headers` config option documentation](/python/configuration/options#option-request_headers) * [Go `request_headers` config option documentation](/go/configuration/options#option-request_headers) * [PHP `request_headers` config option documentation](/php/configuration/options#option-request_headers) ## Recommended headers to filter A non-exhaustive list of request header names that may be used by an application. Do not include these headers, and those like it, in the integrations "request headers" allowlist unless absolutely necessary. * Any personal identifiable headers: * IP Addresses * `Forwarded` * Browser type and versions headers * `User-Agent` * Referrer * `Referer` * Passwords and tokens * `Authorization` * `Proxy-Authorization` * Any custom API token headers. ## See also * [Data filtering guide](/guides/filter-data) - Filter app data in AppSignal integrations # Integrations Source: https://docs.appsignal.com/application/integrations Our integrations are split up in three groups: [Notifiers](#notifiers), [Issue Trackers](#issue-trackers) and [Dashboards](#dashboards) ## Notifiers Notifiers are integrations that connect a 3rd party with the goal of sending notifications for incidents, uptime issues and custom metric triggers. Integrations include [Slack](/application/integrations/slack), [OpsGenie](/application/integrations/opsgenie), [PagerDuty](/application/integrations/pagerduty) and [Microsoft Teams](/application/integrations/teams), see below for a full list of notifiers. To enable notifications for external services, go to the ["Notifications" page](https://appsignal.com/redirect-to/app?to=notifiers) ### Available Notifiers * [Discord](/application/integrations/discord) * [Google Hangouts Chat](/application/integrations/hangouts) * [Microsoft Teams](/application/integrations/teams) * [OpsGenie](/application/integrations/opsgenie) * [PagerDuty](/application/integrations/pagerduty) * [Slack](/application/integrations/slack) * [Squadcast](/application/integrations/squadcast) * [Webhook](/application/integrations/webhooks) ## Third-Party Webhook Integrations Many third-party notifiers offer their own documentation for connecting to AppSignal via our Webhook. For more details, you can read their documentation: * [All Quiet](https://docs.allquiet.app/integrations/inbound/appsignal) * [ilert](https://docs.ilert.com/inbound-integrations/appsignal) * [Squadcast](https://support.squadcast.com/integrations/alert-source-integrations-native/appsignal) * [Zenduty](https://www.zenduty.com/docs/appsignal-integration/) ## Issue Trackers The second category are integrations with issue trackers such as [GitHub](/application/integrations/github), [GitLab](/application/integrations/gitlab), [Trello](/application/integrations/trello) and [Jira](/application/integrations/jira), amongst others. Besides email notifications we can send messages about new exceptions, performance issues and deploys to several 3rd parties. Below is a list of supported external services. Visit our ["Integrations" page](https://appsignal.com/redirect-to/app?to=integrations) in the app navigation and fill out the form for each service you'd like to enable. ### Available Issue Trackers * [Asana](/application/integrations/asana) * [Shortcut](/application/integrations/shortcut) * [GitHub](/application/integrations/github) * [GitLab](/application/integrations/gitlab) * [Jira](/application/integrations/jira) * [Trello](/application/integrations/trello) * [Linear](/application/integrations/linear) ## Dashboards Dashboards can be used to show certain metrics such as error rates, response times and throughput for apps. ### Available Dashboards * [Geckoboard](/application/integrations/geckoboard) # Asana Source: https://docs.appsignal.com/application/integrations/asana Asana is the work management platform teams use to stay focused on the goals, projects, and daily tasks that grow business. Easily organize and plan workflows, projects, and more, so you can keep your team's work on schedule. [Asana][asana] is the work management platform teams use to stay focused on the goals, projects, and daily tasks that grow business. Easily organize and plan workflows, projects, and more, so you can keep your team's work on schedule. Asana is a personal integration set up per user. This means it needs to be configured per user in AppSignal who want to use the Asana integration for AppSignal apps. Create an Asana task in AppSignal ## Adding Asana to your app * First open [Asana][asana] and go to your "Profile settings". * Open the "Apps" tab. * Click on the "Manage Developer Apps" link to get your API token. Asana profile settings - Apps tab * Next, open your app on [AppSignal.com](https://appsignal.com/accounts). * Open the "Integrations" page for the app. * Click on "Configure" for the Asana integration. * Paste your Asana API token in the "API token" field. * Copy and paste the project ID of the Asana project you want to link in the "Project ID" field. * The project ID is part of the Asana URL: `https://app.asana.com/0//board` * Click the "create integration" button to create your Asana integration. The integration has now been created! You can now send errors and performance issues to Asana from the incident details screen. If anything went wrong while validating the integration your will be prompted with the error message. Feel free [contact us](mailto:support@appsignal.com) if you experience any problems while setting up this integration. [asana]: https://asana.com
### Integrations list * [Asana](/application/integrations/asana) * [Discord](/application/integrations/discord) * [Geckoboard](/application/integrations/geckoboard) * [GitLab](/application/integrations/gitlab) * [Google Hangouts Chat](/application/integrations/hangouts) * [Jira](/application/integrations/jira) * [Linear](/application/integrations/linear) * [Microsoft Teams](/application/integrations/teams) * [OpsGenie](/application/integrations/opsgenie) * [PagerDuty](/application/integrations/pagerduty) * [Shortcut](/application/integrations/shortcut) * [Slack](/application/integrations/slack) * [Squadcast](/application/integrations/squadcast) * [Trello](/application/integrations/trello) * [Webhooks](/application/integrations/webhooks) # Discord Source: https://docs.appsignal.com/application/integrations/discord Learn more about how to set up the AppSignal Discord integration. Discord describes themselves as the easiest way to communicate over voice, video, and text, whether you’re part of a school club, a nightly gaming group, a worldwide art community, or just a handful of friends that want to hang out. With this integration you will be able to receive notifications for deploys, errors, performance issues and alerts from AppSignal on Discord. Website: [Discordapp.com](https://discordapp.com) ## On Discordapp.com To create a webhook, click the Settings cog for the desired channel and navigate to the "webhooks" section of the settings page. Screenshot of Discord webhooks page Click "Create webhook" to add a new webhook. You can use the following icon: [AppSignal logo](/assets/images/screenshots/discord/appsignal-logo-square.png) (right click and save-as). Copy the webhook URL and save the integration. ## On Appsignal.com [On AppSignal navigate to the "integrations" page (or click this link).](https://appsignal.com/redirect-to/app?to=notifiers). Select the "Discord" integration from the "Add integration" dropdown and fill out the form. Our Discord integration relies on the `slack` compatible webhook endpoint on Discord, for the webhook, paste the webhook from the Discord integration screen **and append** `/slack` to the url. Screenshot of Discord notifier page on AppSignal.com Save the integration and when succesfully saved, click the "test hook" button to verify the integration is working. You are now ready to receive notifications for deploys, errors, performance issues and alerts from AppSignal on Discord!
### Integrations list * [Asana](/application/integrations/asana) * [Discord](/application/integrations/discord) * [Geckoboard](/application/integrations/geckoboard) * [GitLab](/application/integrations/gitlab) * [Google Hangouts Chat](/application/integrations/hangouts) * [Jira](/application/integrations/jira) * [Linear](/application/integrations/linear) * [Microsoft Teams](/application/integrations/teams) * [OpsGenie](/application/integrations/opsgenie) * [PagerDuty](/application/integrations/pagerduty) * [Shortcut](/application/integrations/shortcut) * [Slack](/application/integrations/slack) * [Squadcast](/application/integrations/squadcast) * [Trello](/application/integrations/trello) * [Webhooks](/application/integrations/webhooks) # Geckoboard Source: https://docs.appsignal.com/application/integrations/geckoboard Use Geckoboard to build clear, effective data dashboards for your business. Use Geckoboard to build clear, effective data dashboards for your business that keep teams informed, motivated and aligned around your KPIs. Website: [https://www.geckoboard.com/](https://www.geckoboard.com/)
### Integrations list * [Asana](/application/integrations/asana) * [Discord](/application/integrations/discord) * [Geckoboard](/application/integrations/geckoboard) * [GitLab](/application/integrations/gitlab) * [Google Hangouts Chat](/application/integrations/hangouts) * [Jira](/application/integrations/jira) * [Linear](/application/integrations/linear) * [Microsoft Teams](/application/integrations/teams) * [OpsGenie](/application/integrations/opsgenie) * [PagerDuty](/application/integrations/pagerduty) * [Shortcut](/application/integrations/shortcut) * [Slack](/application/integrations/slack) * [Squadcast](/application/integrations/squadcast) * [Trello](/application/integrations/trello) * [Webhooks](/application/integrations/webhooks) # GitHub Source: https://docs.appsignal.com/application/integrations/github [GitHub](https://github.com) is a great tool for developers to collaborate on software on. AppSignal integrates with GitHub to help give you more insight into your code and better track and tackle issues. This documentation will walk you through how to properly leverage your AppSignal integration with GitHub. ## Contents * [Link AppSignal to Repo](/application/integrations/github/link-to-repo) * [Link Backtraces to Revisions and Lines](/application/integrations/github/link-backtraces-to-revisions-and-lines) * [Create GitHub Issues for Incidents](/application/integrations/github/create-github-issue) # Create GitHub Issues for Incidents Source: https://docs.appsignal.com/application/integrations/github/create-github-issue Once you've installed the AppSignal GitHub integration, given AppSignal permission to read and write to your GitHub repositories, and connected your AppSignal app to the desired repo, you can convert AppSignal incidents into GitHub issues. ## Instructions Navigate to the relevant namespace for your AppSignal application, click "Performance" in the side navigation, and then "Issue list". From the Performance Measurements page, open the relevant issue. AppSignal Issue List Once the issue is open, click on the "Send to GitHub" button in the top right corner. AppSignal Issue List This will open a screen that allows you to create a GitHub issue. By default a link to the AppSignal incident and when applicale up to 10 lines of back trace will be included in the Issue description. You can modify the title and description of the issue but we recommend including the AppSignal incident link and backtrace. Once completed, you can click "Create GitHub issue" to create the issue in the GitHub repo your application's namespace is connected to. AppSignal Issue List You can change the repo your AppSignal application's namespaces are connected to in your AppSignal application's settings page. You can also manage the access rights of AppSignal in your GitHub integration settings. πŸ›Ÿ If you are having trouble making GitHub issues for AppSignal incidents, please [get in touch](mailto:support@appsignal.com), and we'll help you further. # Link Backtraces to Revisions and Lines Source: https://docs.appsignal.com/application/integrations/github/link-backtraces-to-revisions-and-lines Codebases are rarely static, and changes are often made to them. Depending on how your application is managed, it could see changes being deployed several times a day. This can make pinning down the root of an issue tricky if the code that caused it has been altered. To help you quickly get to the root cause of issues, you can configure AppSignal to provide backtrace links to the relevant revisions of your repository. ## Link AppSignal to GitHub To configure this feature, you first need to link AppSignal to your application's GitHub repo. You can find those instructions in our [Link AppSignal to Repo](/application/integrations/github/link-to-repo) documentation. Once this step is completed, make sure you've [enabled deploy markers](#enable-deploy-markers). ## Enable Deploy Markers Once you've connected AppSignal to your application's GitHub repo, you will need to enable deploy markers. You can find instructions on how to do this in our [Backtrace Links](/application/backtrace-links) documentation. Once this step is completed, AppSignal will automatically link backtraces back to the specific revision, path, and line of code. You can check what repo url your application is using by navigating to the relevant application and clicking on the "App Settings" link at the bottom of the side navigation bar: AppSignal Application Settings You can manage your GitHub integration on the Integrations page, also accessible via "App Settings". # Link AppSignal to Repo Source: https://docs.appsignal.com/application/integrations/github/link-to-repo The following documentation will walk you through all the steps needed to integrate AppSignal with your GitHub Organization's repositories and link them to your AppSignal apps so that you can set up issue tracking. ## Adding Organization issue tracker integrations Head over to your application's [integration](https://appsignal.com/redirect-to/app?to=integrations) page. Click on the "Configure" button for GitHub integration. GitHub AppSignal integration On the next step click on the "Install GitHub app" button. Install GitHub app You will be redirected to GitHub, here you should select your account/organization where the application source code exists. Select GitHub organization You will then be asked to select the repository of your application. Depending on your preference either select "All repositories" or select specific repositories by choosing "Only select repositories". Once done click on "Install & Request" button. Select GitHub repository After this step you will be redirect back to AppSignal where you should link your application in AppSignal with the repository in GitHub using the "linked repository" drop down menu and then click on "Save repository selection" button. Link GitHub repository You are now done, if you head back to your application's [integration](https://appsignal.com/redirect-to/app?to=integrations) page you will notice the integration is now active. Complete GitHub integration ### Troubleshooting If you already linked your organization at GitHub with AppSignal and you are not seeing the repository when you visit the [organization integrations page](https://appsignal.com/redirect-to/organization?to=admin/integrations/github). Then click on the "Configure this integration on GitHub" button. Re-configure GitHub integration You will be redirected to GitHub, make sure you have selected the repository which is missing in AppSignal, or select "All repositories" and click on "Save" button. Re-configure GitHub integration You will be redirected back to AppSignal and you should now be able to see the name of your repository in the "linked repository" drop down. If anything went wrong while validating the integration your will be prompted with the error message. Feel free [contact us](mailto:support@appsignal.com) if you experience any problems while setting up this integration. [github]: https://github.com # GitLab Source: https://docs.appsignal.com/application/integrations/gitlab Connect AppSignal to your GitLab project to view source and link revisions, and report deploys from GitLab CI/CD. Tools for modern developers. GitLab unifies issues, code review, CI and CD into a single UI. The GitLab integration links AppSignal back to your GitLab repository (view source for an exception, open a commit, etc.). It is a **personal integration**: each user who wants to use it must complete these steps for themselves on every AppSignal app. GitLab does not have a one-click AppSignal integration on the GitLab side. The setup below uses a GitLab personal access token, which is officially supported on GitLab.com, GitLab Self-Managed, and GitLab Dedicated. This integration **does not automatically create issues on GitLab**, to prevent story-overload. Website: [https://gitlab.com](https://gitlab.com) ## Step 1. Create a GitLab personal access token 1. Sign in to GitLab and go to your user **Settings**. 2. In the left sidebar, select **Access tokens** (`https://gitlab.com/-/user_settings/personal_access_tokens` on GitLab.com). 3. Select **Add new token** and fill in: * **Token name**: `AppSignal` * **Expiration date**: pick a date that matches your organization's policy. * **Scopes**: select the minimum scopes AppSignal needs to read your project: * `read_api` β€” read-only access to the GitLab API (project metadata, commits, files). * `read_repository` β€” read-only access to repository contents over Git/HTTP. 4. Select **Create personal access token** and **copy the token immediately**. GitLab only shows it once. Use `read_api` + `read_repository` rather than the broad `api` scope. AppSignal only needs to read project information, not write to it. ## Step 2. Add the integration in AppSignal 1. In AppSignal, open the app you want to connect. 2. Go to **App settings β†’ Integrations β†’ GitLab**. 3. Fill in the form: * **Token**: paste the personal access token you created in Step 1. * **GitLab URL**: the full URL to the GitLab project, for example `https://gitlab.com/your-namespace/your-project`. For self-managed GitLab, use your instance hostname, e.g. `https://gitlab.example.com/your-group/your-project`. 4. Select **create integration**. You can return to this page at any time to **update integration** or **remove integration**. ## Step 3. Repeat per user Because this is a personal integration, every teammate who wants source links to resolve in their AppSignal account must repeat Steps 1–2 with their own GitLab token. ## Deploy markers from GitLab CI/CD To report deployments to AppSignal from a GitLab CI/CD pipeline, see the [deploy markers documentation](/application/markers/deploy-markers#gitlab-support) for the recommended `revision` config option approach, or the [Markers API example](/application/markers/deploy-markers#gitlab-cicd-example) if your stack does not include an AppSignal integration. ## Troubleshooting **Source links in AppSignal don't open the correct file.** Re-open **App settings β†’ Integrations β†’ GitLab** in AppSignal and confirm the GitLab URL points to the project root (e.g. `https://gitlab.com/namespace/project`) and not to a subpath, branch, or `.git` URL.
### Integrations list * [Asana](/application/integrations/asana) * [Discord](/application/integrations/discord) * [Geckoboard](/application/integrations/geckoboard) * [GitLab](/application/integrations/gitlab) * [Google Hangouts Chat](/application/integrations/hangouts) * [Jira](/application/integrations/jira) * [Linear](/application/integrations/linear) * [Microsoft Teams](/application/integrations/teams) * [OpsGenie](/application/integrations/opsgenie) * [PagerDuty](/application/integrations/pagerduty) * [Shortcut](/application/integrations/shortcut) * [Slack](/application/integrations/slack) * [Squadcast](/application/integrations/squadcast) * [Trello](/application/integrations/trello) * [Webhooks](/application/integrations/webhooks) # Google Hangouts Chat Source: https://docs.appsignal.com/application/integrations/hangouts From direct messages to group conversations, Google Hangouts Chat helps teams collaborate easily and efficiently. From direct messages to group conversations, Google Hangouts Chat helps teams collaborate easily and efficiently. Google Hangouts Chat is a global integration set up per App. Website: [chat.google.com](https://chat.google.com) ## Adding Google Hangouts Chat to your app Adding the integration consists of two steps, one on Google Hangouts Chat and one on AppSignal. ### Google Hangouts Chat Head to the chat options and select "Configure webhooks' Hangouts Webhook Fill out the fields, for "Avatar url" we suggest: `https://appsignal.com/assets/appsignal-icon-square.png` Configure Hangouts Webhook ### AppSignal On the desired app, head to "Notifiers" and select "Google Hangouts" Hangouts integration on AppSignal Fill out the form and paste the webhook url from step one in the "webhook ur" field. Make sure to pick a descriptive name for the integration such as "#errors channel on Hangouts" Hangouts integration on AppSignal You can test the integration after saving the form, a message should appear in your Hangouts chat. If anything went wrong while validating the integration your will be prompted with the error message. Feel free [contact us](mailto:support@appsignal.com) if you experience any problems while setting up this integration.
### Integrations list * [Asana](/application/integrations/asana) * [Discord](/application/integrations/discord) * [Geckoboard](/application/integrations/geckoboard) * [GitLab](/application/integrations/gitlab) * [Google Hangouts Chat](/application/integrations/hangouts) * [Jira](/application/integrations/jira) * [Linear](/application/integrations/linear) * [Microsoft Teams](/application/integrations/teams) * [OpsGenie](/application/integrations/opsgenie) * [PagerDuty](/application/integrations/pagerduty) * [Shortcut](/application/integrations/shortcut) * [Slack](/application/integrations/slack) * [Squadcast](/application/integrations/squadcast) * [Trello](/application/integrations/trello) * [Webhooks](/application/integrations/webhooks) # Jira Source: https://docs.appsignal.com/application/integrations/jira Jira is the tracker for teams planning and building great products. πŸ—“ This documentation was updated in November 2022 to reflect Jira's user interface changes. If, at the time of reading, you find that our instructions are no longer up-to-date, please [let us know!](mailto:support@appsignal.com) [Jira](https://www.atlassian.com/software/jira) is a tool used for project management. It centers around a ticketing system whereby features, chores, and bugs can be ticketed, tracked, and assigned. AppSignal can be integrated into Jira for the automatic ticketing of incidents. This documentation will guide you through the steps needed to integrate AppSignal into your Jira project. ## Configure Jira Before we can link AppSignal to Jira we need to configure Jira to accept our OAuth request. To do this, click the settings cogwheel (βš™οΈ) on the top-right of the navigation bar and select **Products** from the settings menu. Jira Products Select **"Application links"** from the Products side navigation, then click **"Create link"**. Jira Add Link A pop-up will appear. In the Application URL field, add the address: `https://www.appsignal.com` Jira Add Link Pop Up Jira may show the error: "No response was received from the URL you entered". You may ignore this error and proceed by clicking **"Continue"** You will next be presented with a Review Link screen. You only need to provide an Application name before continuing. Name the application: `AppSignal`, and press continue. Jira Review Link Pop Up ### OAuth Setup Now it's time to configure AppSignal's **"Incoming Authentication"**. To do this, navigate to **"Edit"** on the **"Application links"** screen: Jira Link Edit Hover A **"Configure AppSignal"** pop-up will be opened. Navigate to "Incoming Authentication" on the left menu. Jira Edit Link Auth In the "Incoming OAuth" tab, set up OAuth with the following values: * Consumer Key: `ce2jejafmni3qmnzrfergg9fLpzxmppl` * Consumer Name: `AppSignal` * Public Key: ```text Text theme={null} -----BEGIN CERTIFICATE----- MIIDaDCCAlACCQCmEw1Ty8uuRTANBgkqhkiG9w0BAQsFADB2MQswCQYDVQQGEwJO TDEWMBQGA1UECAwNTm9vcmQtQnJhYmFudDESMBAGA1UEBwwJRGVuIEJvc2NoMRUw EwYDVQQKDAxBcHBTaWduYWwgQlYxJDAiBgkqhkiG9w0BCQEWFWNvbnRhY3RAYXBw c2lnbmFsLmNvbTAeFw0yMjA0MjExMDQ1MjBaFw0yMjA1MjExMDQ1MjBaMHYxCzAJ BgNVBAYTAk5MMRYwFAYDVQQIDA1Ob29yZC1CcmFiYW50MRIwEAYDVQQHDAlEZW4g Qm9zY2gxFTATBgNVBAoMDEFwcFNpZ25hbCBCVjEkMCIGCSqGSIb3DQEJARYVY29u dGFjdEBhcHBzaWduYWwuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC AQEAtts1uBJnpIP89PDrlz7EjmEOBBE9RRjpfEEcPctwyYwgLwlP1rK75Qsi/f/T 4T8jD1Q5uVoaAx03m+OBnAJu016qZI2yaCBDVw4+eZwhD9O4kj9ZvwsOFv+ewme8 Bi4MSh+PpXcZuf+FAtAWEPS0aZlA3tq1DokxiJsu1UjfDGBjpVGRf4vwPhQg9Qaq SPOpFODHX6m2fQvglRUxU6y9pJgXhBUxhkiyAosJOnvVLVVdOJ/cnEM6XRfXMb1I aa7on+2dMjryZktYCZRwWMKBfTP3v4qyWB/keyob9K/BvHi8uDTSbJV62vQ+WJza b3STEtFvLl6o2l8GzSkHVlX8/QIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQAXnutJ HHFo3s+b1pnbRs0uKQ/D8bMUlGQocOh2+7189puEdy161Z6qXbv7QL2Z5uAhd67j I/8h3Fchtiy+PbXAn5L+cTQ8ixPllBq4+WFCnL+lWhV4Pnv+qc6KohBHOfgYL9U0 aKGYe5/eFBdewXE1VT+qfncXOxRSjGr4L5UqqS3672ncl1mEWwX6VN/SiGQ8eQ2h FnBIhGCok9w2GLRmx7bfdQVo0b5ROq1FgWyWJWT+eFRmAJ4ei2YrjmfgAfgVEco3 LfAzOw42KKEkcFLiPLZarCGh15fh7QSdBIVI1aF15vceLONC4EEvxMpFLYljmqIF aXqiZ0iKf9gfCvtP -----END CERTIFICATE----- ``` Click **"Save"**. ## Configuring AppSignal To complete the process of linking your Jira project to AppSignal, AppSignal must be configured to communicate with your Jira project. To do this, open your application in AppSignal. Click "App settings" on at the bottom of the left-hand navigation pane and then click "Integrations": AppSignal Settings Navigate to "Personal issue tracker integrations" and click "Manage" for Jira. Alternatively, follow [this link](https://appsignal.com/redirect-to/app?to=integrations/jira/edit). AppSignal Integrations Scroll down to "Jira installation location" and enter the URL of your Jira project, e.g.: `project-name.appsignal.net`, then click "link AppSignal to Jira. AppSignal Connect Jira You'll be presented with the following authentication screen. Click: "Allow". Jira Connect You'll return to AppSignal. Here you need to select which project and issue type you want to use for AppSignal issues. To proceed, click: **"create integration"** Appsignal Jira Linked Config If this step produces an error message, please read the [errors](#errors) section for further guidance. ## Errors AppSignal requires four fields to be present in Jira: * Labels * Environment * Summary * Description AppSignal will show an error message on completion of setup if fields are missing and specify which ones must be added in Jira. AppSignal Jira Integration Error You will have to add the fields to the Jira screens by going to the "Issues" tab in the "Settings" menu: Jira Setting Issues Then navigate to the "Screens" on the left navigation pane and click on "Configure" for the relevant screen: Jira Screen Options On this "Configure" page Jira will present you with a list of already configured fields. Scroll to the bottom of the page and add the missing required fields. Jira Screen Config Once all fields have been created, you should be able to resume and complete the [configuration your Jira integration from the AppSignal app](#configuring-appsignal). ## Need Help? If you've followed the steps on this page and are still getting stuck, feel free to contact us at [support@appsignal.com](mailto:support@appsignal.com).
### Integrations list * [Asana](/application/integrations/asana) * [Discord](/application/integrations/discord) * [Geckoboard](/application/integrations/geckoboard) * [GitLab](/application/integrations/gitlab) * [Google Hangouts Chat](/application/integrations/hangouts) * [Jira](/application/integrations/jira) * [Linear](/application/integrations/linear) * [Microsoft Teams](/application/integrations/teams) * [OpsGenie](/application/integrations/opsgenie) * [PagerDuty](/application/integrations/pagerduty) * [Shortcut](/application/integrations/shortcut) * [Slack](/application/integrations/slack) * [Squadcast](/application/integrations/squadcast) * [Trello](/application/integrations/trello) * [Webhooks](/application/integrations/webhooks) # Linear Source: https://docs.appsignal.com/application/integrations/linear Linear is a better way to build products. [Linear][linear] is a better way to build products. This issue tracker is built for cycles, and comes with built-in workflows to create focus and routines. The Linear integration must be set up individually for each user in AppSignal who wishes to use it with their AppSignal apps. ## Adding Linear to your app Linear works with OAuth, so you don't need to manually enter any API tokens. To add Linear to your app via AppSignal, [navigate to the integration screen](https://appsignal.com/redirect-to/app?to=integrations/linear/edit) of your desired app, and click the "Add new Linear integration" button. You'll be returned to AppSignal after completing Linear's authorization flow, you can then select the Linear team you'd like to link your app to. Once you've successfully linked Linear to AppSignal you will be able to send errors and performance issues to Linear from the incident details screen. If anything went wrong while validating the integration your will be prompted with the error message. Feel free [contact us](mailto:support@appsignal.com) if you experience any problems while setting up this integration. [linear]: https://linear.app
### Integrations list * [Asana](/application/integrations/asana) * [Discord](/application/integrations/discord) * [Geckoboard](/application/integrations/geckoboard) * [GitLab](/application/integrations/gitlab) * [Google Hangouts Chat](/application/integrations/hangouts) * [Jira](/application/integrations/jira) * [Linear](/application/integrations/linear) * [Microsoft Teams](/application/integrations/teams) * [OpsGenie](/application/integrations/opsgenie) * [PagerDuty](/application/integrations/pagerduty) * [Shortcut](/application/integrations/shortcut) * [Slack](/application/integrations/slack) * [Squadcast](/application/integrations/squadcast) * [Trello](/application/integrations/trello) * [Webhooks](/application/integrations/webhooks) # OpsGenie Source: https://docs.appsignal.com/application/integrations/opsgenie OpsGenie is an alerting and on-call management solution that provides Dev & Ops teams with flexible schedule management, escalations and alerting via email, SMS, and mobile app notifications. OpsGenie is an alerting and on-call management solution that provides Dev & Ops teams with flexible schedule management, escalations and alerting via email, SMS, and mobile app notifications. Website: [https://www.opsgenie.com/](https://www.opsgenie.com/)
### Integrations list * [Asana](/application/integrations/asana) * [Discord](/application/integrations/discord) * [Geckoboard](/application/integrations/geckoboard) * [GitLab](/application/integrations/gitlab) * [Google Hangouts Chat](/application/integrations/hangouts) * [Jira](/application/integrations/jira) * [Linear](/application/integrations/linear) * [Microsoft Teams](/application/integrations/teams) * [OpsGenie](/application/integrations/opsgenie) * [PagerDuty](/application/integrations/pagerduty) * [Shortcut](/application/integrations/shortcut) * [Slack](/application/integrations/slack) * [Squadcast](/application/integrations/squadcast) * [Trello](/application/integrations/trello) * [Webhooks](/application/integrations/webhooks) # PagerDuty Source: https://docs.appsignal.com/application/integrations/pagerduty PagerDuty is a great tool to make sure the right person is notified when an error occurs. [PagerDuty](https://www.pagerduty.com) is a great tool to make sure the right person is notified when an error occurs. AppSignal notifies PagerDuty when performance issues or errors occur. New deploys are not sent to PagerDuty. ## Setup AppSignal requires a `Integration Key` from PagerDuty to send error and performance notifications. You can get the `Integration Key` by adding a "Integration" under "Service" > "Service Directory" > "New service". Make sure that for Integrations "Events API V2" is selected. The other details can be filled out at your own discretion. PagerDuty config After saving the form, you can see the `Integration Key`. Use this key on the AppSignal PagerDuty integration form. PagerDuty config After saving, make sure the integration works by clicking "Test hook". If all goes well, it should trigger an incident on PagerDuty. PagerDuty config As always, if you run into any issues, don't hesitate to contact us at [support@appsignal.com](mailto:support@appsignal.com).
### Integrations list * [Asana](/application/integrations/asana) * [Discord](/application/integrations/discord) * [Geckoboard](/application/integrations/geckoboard) * [GitLab](/application/integrations/gitlab) * [Google Hangouts Chat](/application/integrations/hangouts) * [Jira](/application/integrations/jira) * [Linear](/application/integrations/linear) * [Microsoft Teams](/application/integrations/teams) * [OpsGenie](/application/integrations/opsgenie) * [PagerDuty](/application/integrations/pagerduty) * [Shortcut](/application/integrations/shortcut) * [Slack](/application/integrations/slack) * [Squadcast](/application/integrations/squadcast) * [Trello](/application/integrations/trello) * [Webhooks](/application/integrations/webhooks) # Shortcut Source: https://docs.appsignal.com/application/integrations/shortcut Shortcut describes itself as the first project management platform for software development that brings everyone on every team together to build better products. Shortcut describes itself as the first project management platform for software development that brings everyone on every team together to build better products. The Shortcut integration is a personal integration, each person with access to an app (who wants to be able to use this feature) has to complete these steps. This integration **does not** automatically create issues on Shortcut, to prevent story-overload. Website: [Shortcut.com](https://shortcut.com/) ## Features * Create Shortcut stories for error & performance incidents in AppSignal. * On an incident detail page go to the "Issue trackers" box on the right-hand side of the page. * Click "Send to Shortcut" ## Setting up * API token: * Visit your Shortcut account's API token section: [app.shortcut.com/settings/account/api-tokens](https://app.shortcut.com/settings/account/api-tokens) * Generate a new API token by entering a name for it, e.g. AppSignal. * Click "Generate Token". * The generated token will be displayed. Copy it. * It will have this format: `xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx` * [Visit the AppSignal Shortcut integration page](https://appsignal.com/redirect-to/app?to=integrations/shortcut/edit) for the app you want to link. * Paste the Shortcut API token into the "API token" field. * Workflow state ID * Visit your shortcut Workflow States settings screen: [https://app.shortcut.com/settings/workflow](https://app.shortcut.com/settings/workflow) * Click on the icon next to the default workflow state you'd like your stories to have. This icon shows the story count for that workflow state. * Note the `state:xxxx` in the searchbox, copy the number after `state:` * Paste the number in the Workflow State ID input and * Click the "create integration" button. AppSignal is now set up to use the Shortcut integration!
### Integrations list * [Asana](/application/integrations/asana) * [Discord](/application/integrations/discord) * [Geckoboard](/application/integrations/geckoboard) * [GitLab](/application/integrations/gitlab) * [Google Hangouts Chat](/application/integrations/hangouts) * [Jira](/application/integrations/jira) * [Linear](/application/integrations/linear) * [Microsoft Teams](/application/integrations/teams) * [OpsGenie](/application/integrations/opsgenie) * [PagerDuty](/application/integrations/pagerduty) * [Shortcut](/application/integrations/shortcut) * [Slack](/application/integrations/slack) * [Squadcast](/application/integrations/squadcast) * [Trello](/application/integrations/trello) * [Webhooks](/application/integrations/webhooks) # Slack Source: https://docs.appsignal.com/application/integrations/slack Learn how to install, configure and use the AppSignal Slack integration to get real-time notifications for errors, performance incidents, deploys and alerts. The AppSignal Slack integration sends real-time notifications to your Slack channels when events happen in your monitored applications. Get notified about errors, slow requests, deploys, metric alerts, heartbeat alerts, process monitor alerts and log alerts without leaving Slack. Website: [Slack.com](https://www.slack.com) ## Installation 1. Click the install button below, or in your AppSignal app navigate to **Notifications** and choose **Slack** from the **Add integration** drop-down. 2. You will be shown a page where you can select which AppSignal app to install the Slack notifier for. 3. Click the install button to start the Slack authorization flow. 4. You will be redirected to Slack where you authorize the AppSignal app for your workspace and select the channel where notifications should be posted. 5. After authorization you are redirected back to AppSignal where the Slack notifier is created and ready to use. ## Configuration After installation you can configure which events trigger a Slack notification. On the notifier edit page in AppSignal, you can enable or disable the following notification types: * **Error incidents** β€” a new exception is detected in your app. * **Performance incidents** β€” a request takes longer than expected. * **Deploy markers** β€” a new deploy is recorded. * **Metric alerts** β€” a metric alert trigger opens or closes. * **Heartbeat alerts** β€” a heartbeat check is missed. * **Process monitor alerts** β€” a cron process monitor is missed. * **Log alerts** β€” a log trigger matches. To change the Slack channel or notification preferences, go to **Notifications** in your AppSignal app and click on the Slack notifier you want to edit. You can create multiple Slack notifiers for the same app to send different notification types to different Slack channels. ## What notifications look like Each Slack notification includes contextual details about the event: * **Errors** include the exception name, message, first lines of the backtrace, the action and request path. * **Performance incidents** include the action name, duration, request method and path. * **Deploy markers** include the revision (with a link to compare changes when available), namespace and deploying user. * **Metric alerts** include the trigger name, current value, tags and a link to the alert in AppSignal. * **Heartbeat and process monitor alerts** include the identifier and expected completion time. * **Log alerts** include the trigger name, severity and the matching log message. ## Uninstalling To remove the AppSignal Slack integration, delete the Slack notifier from the **Notifications** page in your AppSignal app. You can also remove the AppSignal app from your Slack workspace in your [Slack app management settings](https://slack.com/apps/manage).
### Integrations list * [Asana](/application/integrations/asana) * [Discord](/application/integrations/discord) * [Geckoboard](/application/integrations/geckoboard) * [GitLab](/application/integrations/gitlab) * [Google Hangouts Chat](/application/integrations/hangouts) * [Jira](/application/integrations/jira) * [Linear](/application/integrations/linear) * [Microsoft Teams](/application/integrations/teams) * [OpsGenie](/application/integrations/opsgenie) * [PagerDuty](/application/integrations/pagerduty) * [Shortcut](/application/integrations/shortcut) * [Slack](/application/integrations/slack) * [Squadcast](/application/integrations/squadcast) * [Trello](/application/integrations/trello) * [Webhooks](/application/integrations/webhooks) # Squadcast Source: https://docs.appsignal.com/application/integrations/squadcast Squadcast helps you get alerted via Phone call, SMS, Email and Push notifications and lets you take actions on those alerts. Squadcast helps you get alerted via Phone call, SMS, Email and Push notifications and lets you take actions on those alerts. AppSignal notifications can be sent to Squadcast via webhooks. Refer the official [Squadcast support documentation](https://support.squadcast.com/docs/appsignal) for configuring these webhooks. Website: [https://www.squadcast.com/](https://www.squadcast.com/)
### Integrations list * [Asana](/application/integrations/asana) * [Discord](/application/integrations/discord) * [Geckoboard](/application/integrations/geckoboard) * [GitLab](/application/integrations/gitlab) * [Google Hangouts Chat](/application/integrations/hangouts) * [Jira](/application/integrations/jira) * [Linear](/application/integrations/linear) * [Microsoft Teams](/application/integrations/teams) * [OpsGenie](/application/integrations/opsgenie) * [PagerDuty](/application/integrations/pagerduty) * [Shortcut](/application/integrations/shortcut) * [Slack](/application/integrations/slack) * [Squadcast](/application/integrations/squadcast) * [Trello](/application/integrations/trello) * [Webhooks](/application/integrations/webhooks) # Microsoft Teams Source: https://docs.appsignal.com/application/integrations/teams Microsoft Teams, the hub for team collaboration in Microsoft 365, integrates the people, content, and tools your team needs to be more engaged and effective. Microsoft Teams, the hub for team collaboration in Microsoft 365, integrates the people, content, and tools your team needs to be more engaged and effective. Microsoft Teams is a global integration set up per App. Website: [microsoft.com/teams](https://microsoft.com/teams) ## Adding MS Teams integration to you app Adding the integration consists of two steps, one on Microsoft Teams and one on AppSignal. ### Create a workflow in MS Team Under the channel options, find the "Workflows" option and search for "Webhook." Select "Post to a channel when a webhook request is received." Enter a name for your workflow and click "Next." Wait for a couple of seconds until the form appears, where you can enter details on where you want to post the webhook. Select the desired channel and click on "Add workflow." Copy the generated webhook URL; you will need this URL to configure the integration on AppSignal. ### AppSignal On the desired app, head to "Notifiers" and select "MS Teams" Teams Webhook Form You can test the integration after saving the form, a message should appear in your MS Teams channels. Teams Webhook Test If anything went wrong while validating the integration your will be prompted with the error message. Feel free [contact us](mailto:support@appsignal.com) if you experience any problems while setting up this integration.
### Integrations list * [Asana](/application/integrations/asana) * [Discord](/application/integrations/discord) * [Geckoboard](/application/integrations/geckoboard) * [GitLab](/application/integrations/gitlab) * [Google Hangouts Chat](/application/integrations/hangouts) * [Jira](/application/integrations/jira) * [Linear](/application/integrations/linear) * [Microsoft Teams](/application/integrations/teams) * [OpsGenie](/application/integrations/opsgenie) * [PagerDuty](/application/integrations/pagerduty) * [Shortcut](/application/integrations/shortcut) * [Slack](/application/integrations/slack) * [Squadcast](/application/integrations/squadcast) * [Trello](/application/integrations/trello) * [Webhooks](/application/integrations/webhooks) # Trello Source: https://docs.appsignal.com/application/integrations/trello Trello makes it easy to organize anything with anyone. Trello makes it easy to organize anything with anyone. Website: [https://trello.com](https://trello.com)
### Integrations list * [Asana](/application/integrations/asana) * [Discord](/application/integrations/discord) * [Geckoboard](/application/integrations/geckoboard) * [GitLab](/application/integrations/gitlab) * [Google Hangouts Chat](/application/integrations/hangouts) * [Jira](/application/integrations/jira) * [Linear](/application/integrations/linear) * [Microsoft Teams](/application/integrations/teams) * [OpsGenie](/application/integrations/opsgenie) * [PagerDuty](/application/integrations/pagerduty) * [Shortcut](/application/integrations/shortcut) * [Slack](/application/integrations/slack) * [Squadcast](/application/integrations/squadcast) * [Trello](/application/integrations/trello) * [Webhooks](/application/integrations/webhooks) # Webhooks Source: https://docs.appsignal.com/application/integrations/webhooks Use webhooks to integrate AppSignal with other 3rd parties or your own system. AppSignal can send notifications of new incidents to several services, see our full list on the [integrations](/application/integrations). We also offer webhooks for these notifications so you handle new incidents in your own system. To receive a webhook, go to the "Notifications" tab the site's sidebar, click the "Add integration" and fill out the URL where you'd like to receive your webhook data. Webhook There are multiple webhooks available. Which payloads the webhook receives can be configured in the configuration form for the webhook as seen in the screenshot above. ## Verifying AppSignal webhook requests To ensure the security of your application, you can verify that incoming webhook requests are genuinely from AppSignal. Verification is done by using a Webhook verification token to validate the request's signature. ### Locating your Webhook Verification Token 1. Navigate to **App settings > Integrations** in your AppSignal dashboard. 2. Configure the webhook integration you want to verify. 3. Here you'll find the integration's **Webhook verification token**. This token is used to validate that the webhook request is from AppSignal. ### Verifying a request When AppSignal sends a webhook request, it includes a signature in the `X-Appsignal-Signature` header. You can validate the request as follows: 1. Concatenate the AppSignal Webhook verification token with the raw request body. 2. Generate a SHA256 hash of the concatenated string. 3. Compare the generated hash to the value in the `X-Appsignal-Signature` header. If the hashes match, the request can be verified as coming from AppSignal. ### Example implementations Below are some examples of how you can verify a request is coming from AppSignal in Ruby, Elixir, Node.js and Python. **Note:** The examples below are illustrative, you may need to adapt them depending on the frameworks, integrations and dependencies your app uses. ```ruby Ruby theme={null} token = Rails.application.credentials.appsignal_webhook_token request_signature = request.headers["X-Appsignal-Signature"] message = request.raw_post signature = OpenSSL::Digest::SHA256.hexdigest(token + message.to_s) if signature == request_signature # logic here end ``` ```elixir Elixir theme={null} token = Application.get_env(:my_app, :appsignal_webhook_token) request_signature = List.first(get_req_header(conn, "x-appsignal-signature")) {:ok, raw_body} = read_body(conn) message = token <> raw_body signature = Base.encode16(:crypto.hash(:sha256, message), case: :lower) if signature == request_signature do # logic here end ``` ```js JavaScript theme={null} const crypto = require("crypto"); const token = process.env.APPSIGNAL_WEBHOOK_TOKEN; const requestSignature = req.headers["x-appsignal-signature"]; let rawBody = req.rawBody; const message = token + rawBody; const signature = crypto.createHash("sha256").update(message).digest("hex"); if (signature === requestSignature) { // logic here } ``` ```python Python theme={null} import hashlib import os token = os.getenv('APPSIGNAL_WEBHOOK_TOKEN') request_signature = request.headers['X-Appsignal-Signature'] raw_body = request.get_data(as_text=True) message = token + raw_body signature = hashlib.sha256(message.encode()).hexdigest() if signature == request_signature: # logic here ``` ## Deploy markers ```json JSON theme={null} { "marker": { "time": "2019-01-10 10:45:41 +0100", "marker_id": "5c3714455ac13f7df09437f0", "site": "My test app", "environment": "development", "revision": "abc123", "user": "tom", "repository": "https://github.com/my_org/my_repo", "url": "https://appsignal.com/test/sites/5bd867fa2213937f3666ae7b/dashboard" } } ``` ### Fields | Field | Type | Description | | -------- | ------------------- | ----------------------------------------------- | | `marker` | `Hash` | The webhook payload concerns a marker incident. | #### Deploy marker sub-fields | Field | Type | Description | | ------------- | -------- | ---------------------------------------------------------------------------------------------- | | `time` | `String` | Timestamp at which the deploy marker was created. | | `marker_id` | `String` | Internal AppSignal marker id for the deploy marker. | | `site` | `String` | App name as seen on AppSignal.com. Using the `site` field instead of `app` for legacy reasons. | | `environment` | `String` | App environment of the app as seen on AppSignal.com. | | `revision` | `String` | The [deploy marker](/application/markers/deploy-markers) revision name. | | `user` | `String` | The user that created the marker. | | `repository` | `String` | Url to the repository as configured for the app on AppSignal.com. | | `url` | `String` | Url to the app on AppSignal.com that triggered the webhook. | ## Exception incidents ```json JSON theme={null} { "exception": { "time": "2019-01-09 09:03:57 UTC", "number": 3, "site": "My test app", "environment": "development", "app_url": "https://appsignal.com/test/sites/5bd867fa2213937f3666ae7b", "url": "https://appsignal.com/test/sites/5bd867fa2213937f3666ae7b/incidents/3?timestamp=2019-01-09T09%3A03%3A57Z", "revision": "abc123", "user": "tom", "namespace": "web", "exception": "Appsignal::Demo::TestError", "message": "Hello world! This is an error used for demonstration purposes.", "app_backtrace": [ "/Users/tombruijn/.gem/ruby/2.5.3/gems/appsignal-2.8.1/lib/appsignal/demo.rb:49:in `create_example_error_request'", "/Users/tombruijn/.gem/ruby/2.5.3/gems/appsignal-2.8.1/lib/appsignal/demo.rb:35:in `transmit'", "/Users/tombruijn/.gem/ruby/2.5.3/gems/appsignal-2.8.1/lib/appsignal/cli/demo.rb:53:in `run'", "/Users/tombruijn/.gem/ruby/2.5.3/gems/appsignal-2.8.1/lib/appsignal/cli.rb:31:in `run'", "/Users/tombruijn/.gem/ruby/2.5.3/gems/appsignal-2.8.1/bin/appsignal:7:in `'", "/Users/tombruijn/.gem/ruby/2.5.3/bin/appsignal:23:in `load'", "/Users/tombruijn/.gem/ruby/2.5.3/bin/appsignal:23:in `'", "/Users/tombruijn/.gem/ruby/2.5.3/bin/bundle:23:in `
'" ], "first_backtrace_line": "/Users/tombruijn/.gem/ruby/2.5.3/gems/appsignal-2.8.1/lib/appsignal/demo.rb:49:in `create_example_error_request'", "action": "DemoController#hello", "path": "/hello", "hostname": "Toms-MacBook-Pro.local", "action_label": "request", "metadata": { "demo_sample": "true", "method": "GET", "path": "/hello" } } } ``` ### Fields | Field | Type | Description | | ----------- | ------------------- | -------------------------------------------------- | | `exception` | `Hash` | The webhook payload concerns a exception incident. | #### Exception sub-fields | Field | Type | Description | | ---------------------- | ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `time` | `String` | Timestamp at which the exception occurred. | | `number` | `Integer` | Incident id as shown on AppSignal.com. | | `site` | `String` | App name as seen on AppSignal.com. Using the `site` field instead of `app` for legacy reasons. | | `environment` | `String` | App environment of the app as seen on AppSignal.com. | | `app_url` | `String` | Url to the app on AppSignal.com that triggered the webhook. | | `url` | `String` | Url to the specific sample for the incident on AppSignal.com that triggered this webhook. | | `revision` | `String` | The [deploy marker](/application/markers/deploy-markers) revision name. | | `user` | `String` | The user that created the marker. The user value can also be `null` if not set for a deploy marker revision. | | `namespace` | `String` | The namespace in which this exception occurred. | | `exception` | `String` | The exception type that was recorded by AppSignal. | | `message` | `String` | The exception message with more details about the exception. | | `app_backtrace` | `Array` | The lines of the backtrace concerning the app from which they originated. This excludes any backtrace lines from libraries that are included in the app. | | `first_backtrace_line` | `String` | The first backtrace line from the `app_backtrace` field. | | `action` | `String` | The action in which this exception occurred. Either a controller action, background worker or a manually set action. | | `path` | `String` | The request path on which the exception occurred. This is only set for web requests. This is metadata set by the AppSignal integration by default and is also included in the `metadata` field. | | `hostname` | `String` | The hostname of the host that this exception occurred on. | | `action_label` | `String` | A human friendly label for the type of action this exception occurred on. Uses `request` for the `web` namespace and `job` for the `background` namespace. All other namespaces use `action`. | | `metadata` | `Hash` | This includes user set metadata (see [Tagging feature](/guides/tagging)). | #### Metadata fields You can add your own metadata by [tagging samples](/guides/tagging). | Field | Type | Description | | ------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `demo_sample` | `String` | Set by the AppSignal integration for demo samples send using our demo command line tool ([Ruby](/ruby/command-line/demo) / [Elixir](/elixir/command-line/demo)). Not set for all other samples. | | `method` | `String` | The request method used to perform a request. Only available for (web) requests. | | `path` | `String` | The request path on which the exception occurred. This is only set for web requests. Contains the same value as the `path` field. | ## Performance incidents ```json JSON theme={null} { "performance": { "time": "2019-01-10 09:38:08 UTC", "number": 1, "site": "My test app", "environment": "development", "app_url": "https://appsignal.com/test/sites/5bd867fa2213937f3666ae7b", "url": "https://appsignal.com/test/sites/5bd867fa2213937f3666ae7b/incidents/1?timestamp=2019-01-10T09%3A38%3A08Z", "revision": "abc123", "user": "tom", "namespace": "web", "duration": 2004.904052734375, "action": "DemoController#hello", "path": "/hello", "hostname": "Toms-MacBook-Pro.local", "action_label": "request", "metadata": { "demo_sample": "true", "method": "GET", "path": "/hello" } } } ``` ### Fields | Field | Type | Description | | ------------- | ------------------- | ---------------------------------------------------- | | `performance` | `Hash` | The webhook payload concerns a performance incident. | #### Performance sub-fields | Field | Type | Description | | -------------- | ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `time` | `String` | Timestamp at which the performance incident occurred. | | `number` | `Integer` | Incident id as shown on AppSignal.com. | | `site` | `String` | App name as seen on AppSignal.com. Using the `site` field instead of `app` for legacy reasons. | | `environment` | `String` | App environment of the app as seen on AppSignal.com. | | `app_url` | `String` | Url to the app on AppSignal.com that triggered the webhook. | | `url` | `String` | Url to the specific sample for the incident on AppSignal.com that triggered this webhook. | | `revision` | `String` | The [deploy marker](/application/markers/deploy-markers) revision name. | | `user` | `String` | The user that created the marker. The user value can also be `null` if not set for a deploy marker revision. | | `namespace` | `String` | The namespace in which this performance incident occurred. | | `duration` | `Float` | The time in milliseconds measured which the request/job/action took to complete. | | `action` | `String` | The action in which this performance incident occurred. Either a controller action, background worker or a manually set action. | | `path` | `String` | The request path on which the performance incident occurred. This is only set for web requests. This is metadata set by the AppSignal integration by default and is also included in the `metadata` field. | | `hostname` | `String` | The hostname of the host that this performance incident occurred on. | | `action_label` | `String` | A human friendly label for the type of action this performance incident occurred on. Uses `request` for the `web` namespace and `job` for the `background` namespace. All other namespaces use `action`. | | `metadata` | `Hash` | This includes user set metadata see [metadata](/guides/tagging). | #### Metadata fields You can add your own metadata by [tagging samples](/guides/tagging). | Field | Type | Description | | ------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `demo_sample` | `String` | Set by the AppSignal integration for demo samples send using our demo command line tool ([Ruby](/ruby/command-line/demo) / [Elixir](/elixir/command-line/demo)). Not set for all other samples. | | `method` | `String` | The request method used to perform a request. Only available for (web) requests. | | `path` | `String` | The request path on which the performance incident occurred. This is only set for web requests. Contains the same value as the `path` field. | ## Anomaly detection ```json JSON theme={null} { "alert_id": "5bdb1fb301925b0c4b6c7017", "state": "closed", "site": "google", "environment": "production", "tags": { "namespace": "web" }, "human_tags": ["namespace: web"], "metric_name": "transaction_exception_rate", "field": "gauge", "trigger_label": "Exception rate", "trigger_description": "This is a description", "last_value": 12.0, "peak_value": 20.0, "mean_value": 11.0, "comparison_operator": "<", "comparison_value": 21.0, "human_last_value": "12 %", "human_peak_value": "20 %", "human_mean_value": "11 %", "human_comparison_value": "21 %", "created_at": "2017-08-01T10:00:00Z", "opened_at": "2017-08-01T10:05:00Z", "resolved_at": "2017-08-01T12:00:00Z", "closed_at": "2017-08-01T13:43:00Z", "warmup_duration": 10, "cooldown_duration": 20, "alert_url": "http://example.com/#{site.account.slug}/sites/#{site.id}/alerts/#{alert.id}", "edit_trigger_url": "http://example.com/#{site.account.slug}/sites/#{site.id}/triggers?overlay=triggerForm&triggerId=#{alert.trigger.id}" } ``` | Field | Type | Description | | ------------------------ | -------- | ---------------------------------------------------------------------------------------------------------------------- | | `alert_id` | `String` | Internal AppSignal alert id for the alert. | | `state` | `String` | [State](/anomaly-detection/#alert-states) of the alert. | | `site` | `String` | The application name alert belongs to. | | `environment` | `String` | The application environment name alert belongs to. | | `tags` | `Array` | Namespace associated with the alert. | | `human_tags` | `Array` | Custom namespace associated with the alert. | | `metric_name` | `String` | Name of the metric alert was created for. | | `field` | `String` | Field name of the alert. | | `trigger_label` | `String` | Name of the trigger. | | `trigger_description` | `String` | Description of the trigger. | | `last_value` | `String` | Last value recorded for the alert. | | `peak_value` | `String` | Highest value recorded for the alert | | `mean_value` | `String` | Mean of all values for the alert. | | `comparison_operator` | `String` | Comparison operator set by the user based on which the alert will be triggered. | | `comparison_value` | `String` | Comparison value of the metric set by the user based on which the alert will be triggered. | | `human_last_value` | `String` | Last metric value that recorded for the alert since it was opened in a more readable format. | | `human_peak_value` | `String` | Highest value of the metric value that was recorded for the alert while it was open. | | `human_mean_value` | `String` | Mean value of the metric value for the alert while it was open in a more readable format. | | `human_comparison_value` | `String` | Comparison value for the alert metric set by the user based on which the alert will be triggered in a readable format. | | `created_at` | `String` | Timestamp at which the alert was created. | | `opened_at` | `String` | Timestamp (ISO8601) at which the alert was opened. | | `resolved_at` | `String` | Timestamp (ISO8601) at which the alert was resolved. | | `closed_at` | `String` | Timestamp (ISO8601) at which the alert was closed. | | `warmup_duration` | `String` | Time in minutes AppSignal waits before opening a alert. | | `cooldown_duration` | `String` | Time in minutes AppSignal waits before closing a alert. | | `alert_url` | `String` | URl of the alert so user can view it on AppSignal. | | `edit_trigger_url` | `String` | URl of the alert so user can edit it on AppSignal. |
### Integrations list * [Asana](/application/integrations/asana) * [Discord](/application/integrations/discord) * [Geckoboard](/application/integrations/geckoboard) * [GitLab](/application/integrations/gitlab) * [Google Hangouts Chat](/application/integrations/hangouts) * [Jira](/application/integrations/jira) * [Linear](/application/integrations/linear) * [Microsoft Teams](/application/integrations/teams) * [OpsGenie](/application/integrations/opsgenie) * [PagerDuty](/application/integrations/pagerduty) * [Shortcut](/application/integrations/shortcut) * [Slack](/application/integrations/slack) * [Squadcast](/application/integrations/squadcast) * [Trello](/application/integrations/trello) * [Webhooks](/application/integrations/webhooks) # Limits Source: https://docs.appsignal.com/application/limits This page is about the **Limits** view in your application's settings. It is not about reducing your billable request count. For that, see [Limiting requests](/support/limiting-requests). The **Limits** page shows the top-10 custom metrics in your app by unique key count from the last recorded minute. Above the table, it also shows your app's total unique keys and the recorded time for that minute. A unique key is one custom metric name plus one combination of tag values. ## What the page shows For each of the top 10 custom metrics, the page lists: * **Metric name:** the name of the custom metric. * **Unique keys:** how many distinct tag combinations were seen in the last recorded minute, and the share of your app's total. * **Tag examples:** a sample of the tag combinations being reported. Use this column to spot tags with many different values. If there are more examples, the page shows a `+ more` link. ## When to use this page If you're seeing gaps in your custom dashboards, use this page to check whether any metric is generating many unique keys. High-cardinality tags are a common cause. To reduce the number of unique keys, review the tags on that metric and use a limited range of tag values when possible. ## See also * [Custom metrics](/metrics/custom) * [Metric tags](/metrics/custom#metric-tags) # Link templates Source: https://docs.appsignal.com/application/link-templates AppSignal supports tagging of requests, as described in our [tagging guide][tagging-guide]. These tags make it possible to generate URLs to your own application to deep link to pages in your own system, such as related user profiles or blog posts. ## Tagging requests For link templates to work AppSignal needs to have the data necessary to create the links. Start by adding tags to request in your application. Add the following code in a location where it's executed for the related request, such as a `before_action` block in a Ruby on Rails application or using Plug in the Elixir Phoenix framework. ```ruby Ruby theme={null} # Ruby example Appsignal.tag_request( :user_id => current_user.id, :account_id => current_account.id ) ``` ```elixir Elixir theme={null} # Elixir example Appsignal.Span.set_sample_data( Appsignal.Tracer.root_span, "tags", %{ locale: "en", user_id: user_id, stripe_customer_id: stripe_customer_id, locale: locale, default_locale: default_locale } ) ``` πŸ“– For more information about tagging requests, please read the [tagging guide][tagging-guide]. ## Log attributes AppSignal can also generate links based on log attributes. For more information about logging and how to add log attributes see our [logging documentation](/logging) ## Creating a link template Link templates can be defined on AppSignal.com per application. The "Link templates" configuration can be found in the ["App settings" section](https://appsignal.com/redirect-to/app?to=edit) in the left-hand side navigation. link templates Link templates can contain variables, defined by wrapping them in percentage signs `%%`. For example, the `user_id` tag can be used in a link like so: ```shell Shell theme={null} https://yourapp.com/backend/users/%user_id% ``` A link can contain as many variables as you like, but in order for a link to be generated, all variables need to be present in the tags of a request. After adding tags in your app and defining link templates, links will be generated for each request in the "Overview" section. link templates ### Customizing link names By default the tags and links table will increment links, e.g. "Link 1", "Link 2", "Link 3". If you want to use more descriptive link names you can do so with this format: ```shell Shell theme={null} [Backend]https://yourapp.com/backend/users/%user_id% ``` [tagging-guide]: /guides/tagging.html # Markers Source: https://docs.appsignal.com/application/markers Markers are little icons used in graphs on AppSignal.com to indicate a change. This can be a code deploy using a "Deploy marker" or a special event with a "Custom marker". Deploy markers can be used to indicate a change in application version that's deployed, grouping together errors and performance issue per deploy. Custom markers can be used for anything from scaling operations, to sudden spikes in traffic and infrastructure issues such as when a database was acting up. # Custom markers Source: https://docs.appsignal.com/application/markers/custom-markers Markers are little icons used in graphs on AppSignal.com to indicate a change. This can be a code deploy using a ["Deploy marker"](/application/markers/deploy-markers) or a special event with a "Custom marker". Custom markers can be used for anything from scaling operations, to sudden spikes in traffic and infrastructure issues such as when a database was acting up. See also our announcement posts about Custom markers: * [Introducing custom markers](https://blog.appsignal.com/2016/10/28/custom-markers.html) * [Add custom markers from any graph](https://blog.appsignal.com/2016/11/28/custom-markers-from-any-graph.html) ## Creating a custom marker A custom marker can be created in two ways. Through the UI on AppSignal.com on the graphs or with a request to our API. ### Using the Graph UI When on AppSignal.com open a page with a graph on it, any graph. Hover over a space in a graph and you will be presented with a "Add marker" button. In the "Add marker" lightbox, select an icon, set a message and create your marker. To edit or delete a marker, click on the icon and you will be brought back to the editor. ### Using the AppSignal API There are two APIs to report custom markers to AppSignal. These two APIs use different authentication methods. Choose the one that's most convenient, there is no other difference. * [Markers API endpoint documentation](/api/markers): authenticate using Personal Access Token. This authentication method has read and write access to all data. * [Public endpoint markers API endpoint documentation](/api/public-endpoint/custom-markers): authenticate using a Push API key + app name and environment, or using a Front-end API key. This authentication method is write only. # Deploy markers Source: https://docs.appsignal.com/application/markers/deploy-markers Markers are little icons used in graphs on AppSignal.com to indicate a change. This can be a code deploy using a "Deploy marker" or a special event with a ["Custom marker"](/application/markers/custom-markers). Deploy markers can also be found in the ["Deploys" section](https://appsignal.com/redirect-to/app?to=markers) in the app navigation which provides a performance overview per deploy. A deploy marker indicates a change in the deployed version of an application. This can be used to group together occurrences of errors and performance issues within a certain time frame. From when the version was deployed until a newer version was deployed. Deploy markers are also required to enable [backtrace links](/application/backtrace-links) for an app. When a new deploy is detected, the list of incidents is empty for the newest deployment version. When an error, or any other issue, is reported by AppSignal in your application it gets listed for the newest deploy as well. On the sample page for an incident you can see in which deployments an incident occurred with the help of the rocket (πŸš€) separator icon. πŸ“– Also read our guide on [how to set up deploy markers](/guides/deploy-markers). Deploy markers in samples list ## Deploy methods There are two methods of notifying AppSignal of a new deploy. These two methods cannot be used together. 1. Using the `revision` config option, and; 2. Creating a deploy notification manually with the AppSignal Push API. The first method (`revision` config option) is our recommended approach, because it's the most reliable method and works better for applications with more than one host. We detect the revision from the application itself so we know which instance is running what version. The second approach (creating a deploy marker manually) is a method only really useful for small applications that use one host. It creates a new deploy marker at a specific time, regardless of the version the application is actually running. This also means it's more error prone. ## Revision config option The recommended approach of letting AppSignal know a new version of your application is deployed is by using the `revision` config option or the `APP_REVISION` environment variable (see the [deploy markers configuration guide](/guides/deploy-markers#configurations-per-language) for more information). This is automatically detected for [Heroku apps](#heroku-support) using the dyno metadata lab feature. This config option is set per instance of an application which has the benefit of every version of an application running at the same time reporting the errors under the correct deploy, rather than the latest deploy that [has been reported](#manually-create-a-deploy-marker) to AppSignal. For example: If one machine is still running an older version of the application all the errors from that instance are reported under the previous deploy marker rather than the last known deploy marker. AppSignal will create a new deploy marker when it receives [transaction data](/appsignal/terminology#transactions). When the revision config option is set for your app, the revision is stored on a transaction that tracks a web request / background job. When our processor on the AppSignal servers detects a new revision it will create a new deploy marker for the parent app with the revision from the transaction. ### Config option The `revision` config option can be used in any integration to report the app's current deploy. See the [deploy markers guide](/guides/deploy-markers) for more information. ```ruby Ruby theme={null} AppSignal.configure do |config| config.revision = "abcdef12" end ``` If you're running a version in which this config option is not available we recommend using the [`APP_REVISION` environment variable](#system-environment-variable) instead. ### System environment variable The `APP_REVISION` value can be any value you use to indicate a version/revision. For example: a version number `1.4.2` or a git SHA `cf8bc42`. The revision value should be set in the application's system environment and updated during a deploy of the application. ```bash Bash theme={null} export APP_REVISION="cf8bc42" # Start your application # bundle exec rackup app.rb ``` ### Heroku support When using Heroku with the [Heroku Labs: Dyno Metadata](https://devcenter.heroku.com/articles/dyno-metadata) enabled, Heroku will populate the `HEROKU_SLUG_COMMIT` environment variable with the SHA of the git commit being deployed. AppSignal will automatically set the `revision` config option to the value of the `HEROKU_SLUG_COMMIT` system environment variable. This will automatically report new deploys when the Heroku app is deployed. ### Render support When deploying an application using Render, it will populate the `RENDER_GIT_COMMIT` environment variable with the SHA of the git commit being deployed. AppSignal will automatically set the `revision` config option to the value of the `RENDER_GIT_COMMIT` system environment variable. This will automatically report new deploys when the Render app is deployed. ### Hatchbox support To use deploy markers with Hatchbox, first connect your Hatchbox account to AppSignal: 1. In Hatchbox, go to your profile settings and navigate to [**Connected accounts**](https://app.hatchbox.io/user/connected_accounts). 2. On the "Connected accounts" page, select **Sign in with AppSignal**. 3. In the AppSignal window that opens, authorize Hatchbox to access your AppSignal organization by selecting **Allow access**. When deploying an application using Hatchbox, it will add a `REVISION` file in the release folder with the SHA of the Git commit being deployed. AppSignal will automatically set the `revision` config option to the value of the `REVISION` file. This will automatically report new deploys when the Hatchbox app is deployed. ### Kamal support When deploying an application using Kamal, it will populate the `KAMAL_VERSION` environment variable within the container with the SHA of the git commit being deployed. AppSignal will automatically set the `revision` config option to the value of the `KAMAL_VERSION` system environment variable. This will automatically report new deploys when the app is deployed using Kamal. ### Docker support If your application runs in a Docker container, follow the instructions below to set your application's revision and create a deploy marker. First, add the following instructions to your Dockerfile, directly after the last `FROM` instruction: ```bash Bash theme={null} ARG COMMIT ENV APP_REVISION=$COMMIT ``` Once added you need to include your application's revision when building your Docker image: ```bash Bash theme={null} docker build --build-arg COMMIT=$(git rev-parse HEAD) -t image:latest ``` When using Fly.io to deploy your application, the `COMMIT` build argument is provided automatically during the build. This will set the `APP_REVISION` environment variable for your application and allow the AppSignal integration to use the revision as a deploy marker. ### GitLab support When deploying from a GitLab CI/CD pipeline, set the `APP_REVISION` environment variable in your deploy job to the commit SHA so AppSignal picks it up when the app starts: ```yaml YAML theme={null} deploy:production: stage: deploy variables: APP_REVISION: $CI_COMMIT_SHA script: - ./bin/deploy.sh ``` `CI_COMMIT_SHA` is one of GitLab's [predefined CI/CD variables](https://docs.gitlab.com/ee/ci/variables/predefined_variables.html) and resolves to the commit being deployed. If your stack does not include an AppSignal integration, see the [GitLab CI/CD example](#gitlab-cicd-example) instead. ## Manually create a deploy marker This method of reporting deploy markers is **deprecated** and may be removed at any time in the future. Reporting deploy markers using this method is only useful for small applications that use one application instance. It creates a new deploy marker at a specific time, regardless of the version the application is actually running. This also means it's also more error prone to group data that shouldn't belong to it under the deploy. We automatically detect deployment by reading the `REVISION` file which Capistrano adds to the release directory since Ruby gem 4.5.18. This method of reporting new deploys to AppSignal requires that you send a POST request to the AppSignal Push API markers endpoint. This can be done with a manual HTTP POST request for other languages. When the deploy marker create/notify request is received by the AppSignal servers, all data that is processed by our servers after that time is tracked under the newly created deploy. To create a Deploy marker with a HTTP POST request you can use curl or some other tool like it. The payload of the request is a JSON object with data about the marker, such as the revision, user who deployed it and the application's repository. Read more about how to create Deploy markers with our API in our [API endpoint](/api/markers) documentation. ### GitLab CI/CD example If you can't use the [`revision` config option](#revision-config-option) β€” for example, because your stack does not include an AppSignal integration β€” you can call the Markers API from a separate GitLab CI/CD job after your deploy succeeds. First, store your AppSignal credentials as masked CI/CD variables in your GitLab project's **Settings β†’ CI/CD β†’ Variables**: * `APPSIGNAL_API_TOKEN` β€” your personal API token (Profile β†’ Account settings β†’ Personal β†’ API). * `APPSIGNAL_APP_ID` β€” the AppSignal app ID for the environment you're deploying. Find it in the AppSignal URL: `https://appsignal.com//sites//...`. Then add a deploy-marker job to your `.gitlab-ci.yml`: ```yaml YAML theme={null} stages: - deploy - notify deploy:production: stage: deploy script: - ./bin/deploy.sh rules: - if: '$CI_COMMIT_BRANCH == "main"' appsignal:deploy_marker: stage: notify image: curlimages/curl:latest needs: ["deploy:production"] rules: - if: '$CI_COMMIT_BRANCH == "main"' script: - | curl --fail --silent --show-error \ -H "Content-Type: application/json" \ -X POST "https://appsignal.com/api/${APPSIGNAL_APP_ID}/markers.json?token=${APPSIGNAL_API_TOKEN}" \ -d "{ \"marker\": { \"kind\": \"deploy\", \"repository\": \"${CI_PROJECT_URL}.git\", \"revision\": \"${CI_COMMIT_SHA}\", \"user\": \"${GITLAB_USER_LOGIN}\" } }" ``` GitLab webhooks cannot be used to call the Markers API directly β€” GitLab webhook payloads have a fixed format that does not match the Markers API request body, and GitLab does not let you transform the payload before sending. #### Troubleshooting If the marker job fails with `401 Unauthorized`, re-check `APPSIGNAL_API_TOKEN`. It must be a personal API token from **Profile β†’ Account settings β†’ Personal β†’ API**, not the Push API key. Confirm the variable is not restricted by Environment scope to a different environment than the job runs in. If the marker job fails with `404 Not Found`, the `APPSIGNAL_APP_ID` is wrong or belongs to a different organization. Copy it from the AppSignal app's URL (`https://appsignal.com//sites//...`). [backtrace links]: /application/backtrace-links.html # Metadata Source: https://docs.appsignal.com/application/metadata You can supply extra context on errors and performance traces using metadata. This can help to add information that is not already part of the request parameters, session data or request headers. πŸ” Do not send Personal Identifiable Information (PII) to AppSignal. Filter PII (e.g., names, emails) and use an ID, hash, or pseudonymized identifier instead.

For HIPAA-covered entities, more info on signing a Business Associate Agreement (BAA) is available in our Business Add-Ons documentation.
πŸ“– Also read our guides on how to set up [metadata](/guides/custom-data) and how to [filter](/guides/filter-data) this metadata. ## Types of metadata To add more complex data structures to error and performance traces, different types of metadata can be used. Some of these are set by our instrumentations automatically and can be overwritten if needed. These are the kind of extra data that can be set. 1. [Request parameters](/guides/custom-data/request-parameters) * If you are using a supported web framework or library, AppSignal will store the request query parameters, request payload body or background job arguments for you automatically. 2. [Request session data](/guides/custom-data/request-session-data) * If you are using a supported web framework, AppSignal will store the request session data for you automatically. 3. [Request headers](/guides/custom-data/request-headers) * If you are using a supported web framework, AppSignal will store the request headers for you automatically. 4. [Function parameters](/guides/custom-data/function-parameters) * Function parameters are the parameters that background jobs or scripts start with. 5. [Custom data](/guides/custom-data/custom-data) * You can use custom data if additional details you want to send are not related to the above three types. AppSignal does not automatically save anything in custom data unless you specifically tell it. # Namespaces Source: https://docs.appsignal.com/application/namespaces Namespaces are a way to group error incidents, performance incidents and metrics from [actions](/appsignal/terminology#actions). [By default](#default-namespaces) AppSignal provides three namespaces: the "web", "background" and "frontend" namespaces. You can add your own namespaces to separate parts of your app like the API or Admin panel with [custom namespaces](#custom-namespaces). πŸ“– Read our guide on [how to set up namespaces][guide]. ## What can you do with namespaces? Let's start first with the things we can use namespaces for: * Group [error incidents](https://appsignal.com/redirect-to/app?to=exceptions) and [performance measurements](https://appsignal.com/redirect-to/app?to=performance) per namespace. Create overviews of the most important namespaces and fix those incidents first. * Track and graph metrics per namespace ([error rate, error count](https://appsignal.com/redirect-to/app?to=exceptions/graphs), [throughput, response times, queue times](https://appsignal.com/redirect-to/app?to=performance/graphs), and more). * Receive [Anomaly detection alerts per namespace](/anomaly-detection/). * Set up [notifications settings per namespace](/application/notification-settings). App Graphs Namespaces ## Default namespaces The "web" namespace holds all data for HTTP requests while the "background" namespace contains metrics from background job libraries and tasks. The "frontend" namespace is created by the [JavaScript front-end integration](/front-end). You can add your own namespaces to separate parts of your app like the API and Admin panel. ## Custom namespaces πŸ“– The custom namespaces feature was introduced in AppSignal for Ruby gem version 2.3.0 and AppSignal for Elixir package version 1.3.0. Using more than one namespace makes it easier to group metrics belonging to the same part of an application together. In AppSignal we use custom namespaces to accomplish this. The advantage of custom namespaces is the ability to group together error and performance incidents from separate parts of the same application. Think of an administration panel, public homepage versus private back-end, etc. The metrics from these three parts in one namespace can clutter the "web" namespace with incidents of varying importance. For example, when something in the administration panel breaks it's not as big of a problem when the sign up page breaks on the public front-end. The metrics from separate parts of an application can be grouped together in their own namespace. By using the AppSignal instrumentation helpers for setting a namespaces it's possible to assign [transactions](/appsignal/terminology#transactions) to a certain namespace. Once the namespace is configured and the application is sending data to the AppSignal, the new namespace will appear in the navigation on AppSignal.com. Note: Data previously reported for the same action is not moved to the new namespace. πŸ“– To set up custom namespaces in your app, read our guide to [setting up namespace with our integrations][guide]. Only letters and underscores are accepted for namespace names. ## Namespace limitations Namespaces are great to split out certain parts of your application, but there are a few limits to namespaces. For optimal performance it's recommended to not have more than **10-15** namespaces maximum. While we don't have a hard-limit on this number, we cannot guarantee performance when more than **15** namespaces are used. ## Ignoring namespaces Sometimes you have a certain part of an application that does not need to be monitored by AppSignal. The most common use case is an administration panel that you use internally which doesn't need constant monitoring. By ignoring an entire namespace AppSignal will ignore all transactional data from all actions in the configured namespaces. To ignore a namespace first make sure to configure AppSignal to report all actions you want to ignore under a certain namespace, as described in the [namespaces guide][guide]. Then configure AppSignal in your app to ignore the namespace, see our [ignore namespaces guide][ignore guide]. After restarting/deploying your app the actions in the selected namespace should no longer be reported on AppSignal.com. πŸ“– To configure AppSignal to ignore namespaces in your app, read our guide to [ignoring namespace with our integrations][ignore guide]. ## Deleting namespaces If you created a namespace that is no longer active you can delete it from the [namespaces](https://appsignal.com/redirect-to/app?to=namespaces) screen under app settings. We do not automatically delete a namespace if it is no longer receiving data. [guide]: /guides/namespaces.html [ignore guide]: /guides/filter-data/ignore-namespaces.html # Notification settings Source: https://docs.appsignal.com/application/notification-settings Whenever AppSignal detects a new error or performance measurement, we open an incident. You can find the incidents in the [Errors](https://appsignal.com/redirect-to/app?to=exceptions) and [Performance](https://appsignal.com/redirect-to/app?to=performance) sections. AppSignal can send out notifications whenever a new incident, or new instances of an already existing incident, is detected. Notifications can happen by email or by one of our [many notifiers](/application/integrations/). ## Notification options Whenever a new incident gets created it will inherit the [app's notification defaults](#app-notification-defaults). When an [Error](#error-incident-notification-settings) or [Performance](#performance-incident-notification-settings) incident has been created, its notification settings can be changed on the incident page itself. If an incident was closed, it will be reopened when a new notification is sent out. There are six notification options available: * [Every Occurrence](#every-occurrence) * [First in Deploy](#first-in-deploy) * [First After Close](#first-after-close) * [Never Notify](#never-notify) * [Every Nth per Hour](#every-nth-per-hourday) * [Every Nth per Day](#every-nth-per-hourday) New error incidents default to **First in Deploy**, and new performance incidents default to **Never Notify**. ### Every Occurrence A notification is sent every time an incident is triggered. This option has a cool down of 5 minutes. This means that if an incident is triggered 20 times a minute, for 20 minutes, you'll receive a notification on minute 0, 5, 10, 15 and 20. ### First in Deploy A notification is sent on the first occurrence of an incident after a new deploy marker is received. You'll need to set up [deploy markers](/application/markers/deploy-markers) for AppSignal to detect a deploy and know when an incident occurred for the first time in a deploy. ### First After Close A notification is sent at the first occurrence of an incident after the incident was previously closed. Incidents can opened and closed in the sidebar in the Incident detail page. This option is a good option for incidents that aren't triggered by a code bug, but out an outside source (e.g. 3rd party has a connection issue) and can't be closed by deploying a new version of the app. ### Never Notify No notification is ever sent out when the incident is triggered. Mostly used for errors that will continue to happen and you'd like to keep track of, but aren't getting fixed soon. If you don't want to receive the incident at all, [ignoring the action](/application/data-collection#ignore-actions) or [ignoring the error](/application/data-collection#ignore-errors) may help. ### Every Nth per Hour/Day No notification is sent every nth time per hour, or day, depending on your preferences. There are many scenarios where this may be beneficial: * **Billing Error:** Imagine a billing error occurring now and then, outside of your control. It happens a maximum of 5 times a day, and you want to know when this suddenly increases. Setting it to "every 10th time a day" will send you an alert on every 10th, 20th, 30th occurrence, etc. * **API Error:** You might have an API that many people use. When experimenting with an API, making mistakes that trigger errors is common. You might only want to be alerted when the number of errors reaches a threshold. You could, for instance, set it to notify you every 1000th time an hour, which might indicate that the API is failing for different reasons. * **During Incident:** Imagine something is severely broken. Hundreds of errors an hour are happening, but you're on top of it. It might not be a good idea to ignore all alerts completely, but getting each one of them will drown you in notifications. This is the perfect moment to manage the number of notifications you receive by temporarily setting your errors to Nth/hour. Visualization of notifications every 100th per hour Above is a visualization of when you would receive alerts. In this scenario, notifications are set to "Every 100th per hour". ## Error incident notification settings Error incidents are identified by the error (class)name, such as `ActiveRecord::RecordNotFound` and if the error happened inside of an action, the action name. (e.g. `StandardError` in `BlogpostsController#show`). Error incident notification options ## Performance incident notification settings Performance incidents are identified by their "action" name, such as `BlogpostsController#show`. Once we detect a new action we create an incident for it. At this point you can override the default notification settings and change when you'd like to be notified and what threshold the duration of the performance incident has to reach before a notification is sent. E.g. for actions where response times can be slow, because they interact with 3rd parties, you can set the duration threshold to 10 seconds, while for the homepage you can set a threshold of 200 milliseconds. The threshold filter is used in combination with the notification settings. E.g. if you have **First in deploy** and **200ms** as the notification settings and threshold, an incident occurrence has to satisfy both in order for a notification to be sent out. Performance incident notification options ## Organization and app namespace defaults Notification settings on an incident can only be changed after it has occurred at least once. This can be an issue if you never want to be notified, or want to set a different performance incident threshold than the default 200 milliseconds. It's possible to configure notification defaults [per app namespace](#app-notification-defaults) or even [for the entire organization](#organization-notification-defaults). This will make it easier to apply the desired notification settings to all new incidents and all existing incidents, for which the notification settings haven't been customized. ### App notification defaults Each application has its own [namespace defaults][app notifications] for notification settings. A new incident in the specified namespace will inherit the default settings set on this page. For more information, see the [notification defaults inheritance](#notification-defaults-inheritance) section. It's recommended to split up the application in [namespaces](/application/namespaces) that group potential incidents by severity. This way you can configure notification settings for a group of incidents and there's no need to configure each incident separately. For example, for an app's admin panel you could create a namespace called `admin` with a default notification setting of "Never notify" as errors that occur in this namespace have less priority. ### Organization notification defaults It's also possible to set up notification defaults on your organization. These defaults will be used when AppSignal detects and creates a new application. When it creates the new app it will apply the organization's notification defaults as the app's app notification defaults. Changes to the organization notification defaults do not apply to already existing apps. For more information, see the [notification defaults inheritance](#notification-defaults-inheritance) section. These organization level [notification defaults][org notifications] can be set up in the organization's admin panel. It's possible to configure defaults for each namespace detected in any of the current applications in your organization. ## Notification defaults inheritance The notification settings bubble up from the incident settings to the app's namespace settings. If the notification settings for an incident aren't changed the app's namespace defaults are used. This means you can also change all the incident notification settings for incidents that haven't customized their notification settings by changing the app defaults. * When a new app is detected by AppSignal, the [organization's namespace defaults][org notifications] are applied. * When organization namespace notification defaults are changed, they only apply to new apps. * When an [app's namespace notification defaults][app notifications] are changed, they apply to all new incidents and existing incidents without customized notification settings. * When a new incident is detected by AppSignal, the [app's namespace defaults][app notifications] are used. * When an incident's notification settings are customized, the incident's customized notification settings are used from then on. [app notifications]: https://appsignal.com/redirect-to/app?to=notifications [org notifications]: https://appsignal.com/redirect-to/organization?to=admin/notifications/edit # Parameter filtering Source: https://docs.appsignal.com/application/parameter-filtering For every request made on a web app, AppSignal collects the parameters that were sent with the request. This includes form data (POST), query parameters and keys in routes, e.g. `/user/:id/` in some frameworks. Data sent to applications that is sensitive or personally identifiable information should not leave the application. To prevent AppSignal from storing this data the integrations need to be configured to not send this data at all or filter out specific values. Parameter filtering ensures that no passwords, email addresses, two-factor authentication token, API tokens, sent to your application are stored in AppSignal. πŸ” Do not send Personal Identifiable Information (PII) to AppSignal. Filter PII (e.g., names, emails) and use an ID, hash, or pseudonymized identifier instead.

For HIPAA-covered entities, more info on signing a Business Associate Agreement (BAA) is available in our Business Add-Ons documentation.
## Integration parameter filtering All AppSignal integrations have a parameter filtering system. A list of parameter keys can be configured to be filtered out, e.g. email, password, two factor authentication API tokens, etc. This way the data is filtered out before it's sent to the AppSignal servers. Any parameter values that are filtered out by these systems will be replaced with a `[FILTERED]` value. This way the list of parameters in the app data on AppSignal.com still includes the parameter key, but not the value. Making it easier to see that a value was sent, but the potentially sensitive data was filtered out. πŸ“– Read our guide about [setting up parameter filtering](/guides/filter-data/filter-parameters) for your app. ### Filter all parameters To filter all parameters without individual parameter filtering, set "send parameters" config option to "false" in the integration configuration. * [Ruby `send_params` config option documentation](/ruby/configuration/options#option-send_params) * [Elixir `send_params` config option documentation](/elixir/configuration/options#option-send_params) * [Node.js `sendParams` config option documentation](/nodejs/3.x/configuration/options#option-sendparams) * [Python `send_params` config option documentation](/python/configuration/options#option-send_params) * Go [`send_request_query_parameters` config option](/go/configuration/options#option-send_request_query_parameters) and [`send_request_payload` config option](/go/configuration/options#option-send_request_payload) documentation * PHP [`send_request_query_parameters` config option](/php/configuration/options#option-send_request_query_parameters) and [`send_request_payload` config option](/php/configuration/options#option-send_request_payload) documentation ## Processor parameter filtering When some sensitive parameters are still sent by your app to AppSignal, we will filter these out during processing. This means the data was sent to our servers, where we received and temporarily store this "pre-processing data". AppSignal filters out [a list of keys](#processor-filtered-keys) from the parameters during processing. These keys are not customizable. These filtered values are replaced with `[REMOVED]` (rather than `[FILTERED]`) to indicate these values were filtered in our processors rather than in your app. Only after this processing, your data is viewable on AppSignal.com. Before that, none of the potentially sent sensitive data is visible to any member of your organization on AppSignal.com. The pre-processing data is removed shortly after processing. This step should **not** be relied upon. If a parameter value is shown as `[REMOVED]` on AppSignal.com, the app's config should be updated to filter out the parameter instead. This way sensitive data does not leave your app. *We always use SSL to encrypt data being sent between your apps and our servers. Any app data containing values that are removed by the processor is deleted shortly after processing.* ### Processor filtered keys The current list of filtered parameter keys by the processor: * `password` * `password_confirmation` ## Recommended keys to filter A non-exhaustive list of parameter keys that may be used by an application. Pick those keys that are relevant for your applications. * Names * `name` * `full_name` * `first_name` * `last_name` * Email addresses * `email` * `email_address` * Passwords * `password` * `password_confirmation` * `confirm_password` * (API) tokens * `token` * `api_token` * Addresses * `street` * `city` * `country` * `post_code` * User information * `phone_number` ## Managing PII and HIPAA Requirements If your app processes Personal Health Information (PHI) and you're a HIPAA-covered entity, you can sign a Business Associate Agreement (BAA) with AppSignal to ensure HIPAA compliance. More information about this can be found in our [Business Add-Ons documentation](/support/business-add-ons). ## See also * [Data filtering guide](/guides/filter-data) - Filter app data in AppSignal integrations # Session data filtering Source: https://docs.appsignal.com/application/session-data-filtering AppSignal gathers session data for HTTP requests by default for supported frameworks. This data may help track down errors or performance issues that were caused by some session data an app is using. Some of this session data may contain sensitive user information though which should not be sent to the AppSignal servers. Use session data filtering to [filter out specific keys](#filter-session-data) or [disable the feature entirely](#filter-all-session-data). πŸ” Do not send Personal Identifiable Information (PII) to AppSignal. Filter PII (e.g., names, emails) and use an ID, hash, or pseudonymized identifier instead.

For HIPAA-covered entities, more info on signing a Business Associate Agreement (BAA) is available in our Business Add-Ons documentation.
## Filter session data An app's session data can be filtered by configuring keys in a *denylist*. This denylist system will filter out all the session data keys configured in this list. Any session data values that are filtered out by these systems will be replaced with a `[FILTERED]` value. This way the list of session data in the app data on AppSignal.com still includes the session data key, but not the value. Making it easier to see that a value was present, but the potentially sensitive data was filtered out. πŸ“– Read our guide about [setting up session data filtering](/guides/filter-data/filter-session-data) for your app. ## Filter all session data To filter all session data without individual key filtering, set the "send session data" config option to "false" in the integration configuration. * [Ruby `send_session_data` config option documentation](/ruby/configuration/options#option-send_session_data) * [Elixir `send_session_data` config option documentation](/elixir/configuration/options#option-send_session_data) * [Node.js `sendSessionData` config option documentation](/nodejs/3.x/configuration/options#option-send_session_data) * [Python `send_session_data` config option documentation](/python/configuration/options#option-send_session_data) * [Go `send_request_session_data` config option documentation](/go/configuration/options#option-send_request_session_data) * [PHP `send_request_session_data` config option documentation](/php/configuration/options#option-send_request_session_data) ## Recommended keys to filter A non-exhaustive list of session data keys that may be used by an application. Pick those keys that are relevant for your applications. * Email addresses * `email` * `email_address` * Tokens * `token` * `api_token` * `sign_up_token` * `reset_password_token` ## Managing PII and HIPAA Requirements If your app processes Personal Health Information (PHI) and you're a HIPAA-covered entity, you can sign a Business Associate Agreement (BAA) with AppSignal to ensure HIPAA compliance. More information about this can be found in our [Business Add-Ons documentation](/support/business-add-ons). ## See also * [Data filtering guide](/guides/filter-data) - Filter app data in AppSignal integrations # Application settings Source: https://docs.appsignal.com/application/settings All settings for an application can be found by clicking the "App Settings" link in the main menu after you've navigated to an application. ## General If your app is not connected to a repository on GitHub you can connect it. If it is connected you can change the linked repository. You need to authenticate with GitHub to use this feature. You can either do this by signing in via GitHub, or by linking your GitHub account in your [user settings](/user-account). An application linked to GitHub gives you additional features like direct links to commits. [Visit the "General" page for your app](https://appsignal.com/redirect-to/app?to=edit) ## Notifications AppSignal can send alert for a number of events. Configure when a notification is sent on this page. See the [application integrations page](/application/integrations) to configure where the notification is sent to. [Visit the Notifications page for your app](https://appsignal.com/redirect-to/app?to=notifiers) ## Team permissions This page gives an overview of the teams and people that have access to an application. You can change the owners and permissions by editing clicking on the "Manage owners|this team" link. Read more about [team management](/organization/team/members) in the Organization topic. [Visit the Team permissions page for your app](https://appsignal.com/redirect-to/app?to=teams) App settings teams ## Push & Deploy On the "Push & Deploy" page you can find your application's "Push API Key" and some snippets to set up deploy notifications. [Visit the Push & Deploy page for your app](https://appsignal.com/redirect-to/app?to=info) # Tagging Source: https://docs.appsignal.com/application/tagging You can supply extra context on errors and performance traces using tags. Tags are key-value data that can be used to search and filter data. πŸ” Do not send Personal Identifiable Information (PII) to AppSignal. Filter PII (e.g., names, emails) and use an ID, hash, or pseudonymized identifier instead.

Use [Link Templates](https://docs.appsignal.com/application/link-templates) to link them back in your app.
πŸ“– Also read our guides on how to set up [tags](/guides/tagging). ## Tags Tags can be used to add information that is not already part of the trace [metadata](/application/metadata) (request parameters, session data, request headers, etc.). Using tags you can easily add more information to errors and performance issues tracked by AppSignal. Maybe while debugging an issue you want to know which user faced the problem, you can pass in the user id or maybe to easily access the user data you can pass in the URL of your admin panel (using link templates) which will take you directly to the customer page. ### Link templates Tags can also be used to create link templates. Read more about link templates in our [link templates guide](/application/link-templates). # Contributing Source: https://docs.appsignal.com/appsignal/contributing Interested in contributing to AppSignal? Great! Helping out is possible in many ways. By reporting issues, fixing bugs, adding features and even fixing typos. [Let us know][contact] if you have any questions about contributing to any of our projects. We're very happy sending anyone who contributes Stroopwafels. Have look at everyone we sent a package to so far on our [Stroopwafels page][waffles-page]. ## Open Source projects All open source projects are available on our [AppSignal GitHub organization][github-appsignal]. Our main projects include: * [AppSignal Ruby library][appsignal-ruby] * [AppSignal Elixir library][appsignal-elixir] * [AppSignal Front-end JavaScript library][appsignal-javascript] * [AppSignal Node.js library][appsignal-nodejs] * [AppSignal Examples applications][appsignal-examples] Other projects we have open sourced, and are used internally by other projects, include: * [AppSignal Rust agent][appsignal-rust] Early stage proof of concept of AppSignal Rust integration. * [sql\_lexer][sql_lexer] Rust library to lex and sanitize SQL queries. * [probes.rs][probes-rs] Rust library to read out system stats from a machine running Linux. * [public\_config][public_config] Parts of AppSignal.com configuration that are public, such as magic dashboards. ## Using git and GitHub We organize most of our git repositories on GitHub using a `main` and `develop` branch. The `main` branch corresponds to the current stable release of a project. The `develop` branch is used for development of features that will end up in the next minor release of a project. Feature branches are used to submit bug fixes and new features using GitHub Pull Requests. When submitting a Pull Request the changes are tested against a variety of Ruby/Elixir versions and dependencies. The submitted change is also reviewed by two or more AppSignal project members before it is accepted. ## Versioning AppSignal is very open about changes to its product. Changes to integrations and the application itself are all visible on [AppSignal.com/changelog][changelog]. Big updates will also be posted on [our blog][blog]. All AppSignal integration projects use [Semantic Versioning][semver] for versioning of releases. Documentation and other non-version specific projects do not use explicit versioning, but will mention related version specific content, such as in which version a feature was introduced. Every stable and unstable release is tagged in git with a version tag and can be found on every project's GitHub page under "Releases". ## Reporting bugs Report a bug by opening an issue on the GitHub project page of the respective project. If the bug report contains some sensitive information that is necessary for the complete report you can also [contact us][contact] to submit the bug. When the bug is a security sensitive issue, please refer to the [Security issues](#security-issues) section. When submitting a bug fix please create a Pull Request on the project's GitHub page please submit the change against the `main` branch. ## Feature requests Missing a feature or integration in AppSignal? Please let us know when something comes to mind by [sending us an email][contact] or submitting an issue on the project's GitHub page. It's also possible to submit a feature on one of our Open Source projects by creating a Pull Request targeted on the project's `develop` branch. ## Security issues If you think you've found a security issue with regards to our application, network or integrations, please let us know immediately by sending an email to [security@appsignal.com](mailto:security@appsignal.com). ## Code of Conduct Everyone interacting in AppSignal's codebases and issue trackers is expected to follow the contributor [code of conduct][coc]. Please report unacceptable behavior to [contact@appsignal.com][coc-contact]. [contact]: mailto:support@appsignal.com [blog]: https://blog.appsignal.com/ [changelog]: https://www.appsignal.com/changelog [waffles-page]: https://www.appsignal.com/waffles [appsignal-ruby]: https://github.com/appsignal/appsignal-ruby [appsignal-elixir]: https://github.com/appsignal/appsignal-elixir [appsignal-javascript]: https://github.com/appsignal/appsignal-javascript [appsignal-nodejs]: https://github.com/appsignal/appsignal-nodejs [appsignal-rust]: https://github.com/appsignal/appsignal-rs [appsignal-examples]: https://github.com/appsignal/appsignal-examples [sql_lexer]: https://github.com/appsignal/sql_lexer [probes-rs]: https://github.com/appsignal/probes-rs [public_config]: https://github.com/appsignal/public_config [github-appsignal]: https://github.com/appsignal [semver]: http://semver.org/ [coc-contact]: mailto:contact@appsignal.com [coc]: /appsignal/contributing/code-of-conduct.html # Code of Conduct Source: https://docs.appsignal.com/appsignal/contributing/code-of-conduct This Code of Conduct applies to [all AppSignal projects](/appsignal/contributing#open-source-projects). ## Our Pledge In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation. ## Our Standards Examples of behavior that contributes to creating a positive environment include: * Using welcoming and inclusive language * Being respectful of differing viewpoints and experiences * Gracefully accepting constructive criticism * Focusing on what is best for the community * Showing empathy towards other community members Examples of unacceptable behavior by participants include: * The use of sexualized language or imagery and unwelcome sexual attention or advances * Trolling, insulting/derogatory comments, and personal or political attacks * Public or private harassment * Publishing others' private information, such as a physical or electronic address, without explicit permission * Other conduct which could reasonably be considered inappropriate in a professional setting ## Our Responsibilities Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. ## Scope This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. ## Enforcement Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at [contact@appsignal.com][coc-contact]. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. ## Attribution This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [https://www.contributor-covenant.org/version/1/4/code-of-conduct.html](https://www.contributor-covenant.org/version/1/4/code-of-conduct.html) [homepage]: https://www.contributor-covenant.org [coc-contact]: mailto:contact@appsignal.com For answers to common questions about this code of conduct, see [https://www.contributor-covenant.org/faq](https://www.contributor-covenant.org/faq) # The life cycle of app data Source: https://docs.appsignal.com/appsignal/data-life-cycle There are a lot of moving parts working together to get the data from apps on your servers to AppSignal's servers and finally in a human readable format on AppSignal.com. This page will describe the process data from apps follow to become incident data, entries in tables, points in graphs, alerts for [Anomaly detection](/anomaly-detection) and notifications. AppSignal is eventually consistent. This means that, even though we try to minimize this, there is no arbitrary duration between a request, background job or metric data being recorded in an app and this data being displayed data on AppSignal.com. Requests that are sent later than others will appear first in AppSignal.com. By breaking down the process we can tell you why this happens. ## Language libraries The AppSignal language libraries ([Ruby](/ruby), [Elixir](/elixir), [JavaScript for Front-end](/front-end)) collect transaction and metrics data. [Transactions](/appsignal/terminology#transactions) are HTTP requests, background jobs and other custom transactions. Metrics data is based on the transaction data but can also be set using our [custom metrics](/metrics/custom). Each incoming HTTP request, or background job, is wrapped in a "transaction". This transaction collects all instrumentation that's being generated during the request, this includes events, parameters, session data and tags. When your app has served the request, the transaction is closed and sent to our agent and placed into a queue. This queue consists of transaction and metrics data. The [AppSignal agent](/appsignal/terminology#agent) transmits this transaction and metrics data in combined payloads every 30 seconds to the [Push API](#push-api). The transmission interval for app instances do not all occur at the same exact time. Exactly when the agent transmits data is based on when in a minute the agent was started. This means that data for the same second on two different app instances can arrive about 30 seconds apart, not including retries. This the reason AppSignal is eventually consistent. Read more about how the language libraries, our extension and agent work together to get the data from your app to the AppSignal servers on the [How our integrations operate](/appsignal/how-appsignal-operates) page. ## Push API Our Push API only has one purpose, to receive data from apps and push it onto a queue as fast and efficiently as possible. From here our processors start processing the transaction and metric data from the apps. ## Processing The AppSignal processor will store new samples for errors and performance measurements based on the transactions, create new incidents or update existing incidents, create metrics based on the transaction data and process custom metrics. During this process we also detect changes in metrics specified in Anomaly detection Triggers to create and notify about new and on going alerts. Read more about how this is done in the [Anomaly detection](#anomaly-detection) section. The processed data then gets stored in our data buckets. This is split between minutely and hourly metrics buckets for your organization. We store data in the minutely resolution for up to 12 hours, after which it is still available in the hourly resolution. Finally when all the processing is done we send out [notifications](/application/integrations/) for new errors, new performance measurements, deploys and [Anomaly detection](#anomaly-detection) alerts. ### Anomaly detection When metric data arrives in our processors, or is created by our processors, they are not immediately used to process [Anomaly detection](/anomaly-detection) Triggers to create or update alerts. The AppSignal processors wait for up to *180 seconds* (3 minutes) before processing data for a minute. This delay about the same maximum delay \[1] it takes for metrics to appear in graphs on AppSignal.com. Read on to learn why this processing delay is present. #### Transmitting the data Like transaction data from language libraries, metrics data goes through multiple systems to end up at our servers. This process takes time. Our processor needs to wait for the AppSignal agent transmission interval after a minute has passed, before it can process data for that minute. #### Clock drift on app servers Read more about how AppSignal handles time, what clock drift is and how to set up NTP synchronization on our [about time page](/support/about-time). #### Processing of metrics data After waiting for up to *180 seconds* (3 minutes) the processor determines that all the data for a minute is present, and it will start processing triggers and creating or updating alerts. It will look back *180 seconds* (3 minutes) since the last data has arrived for an application. Data that is older will be ignored for processing triggers and alerts that processing tick. When the processor has finished processing metrics for a minute, it will start sending out notifications shortly after for new, on going and closed alerts. To extend this delay longer would also mean that notifications arrive later. To reduce this delay would mean we could miss data for a minute providing alerts and notifications about metric data that is incomplete. ## Conclusion It can take up to *90 seconds* for transaction and metrics data to appear. This is a worst-case scenario. If it hasn't appeared after that time something has gone wrong somewhere in the transmission or processing pipeline. It takes *180 seconds* (3 minutes) for metrics graphs and Anomaly detection alerts to be created/updated. We're constantly trying to minimize this time, but have to balance the amount of requests our Push API receives and data size of each request with processing speed. If you would like to know more about this subject, don't hesitate to [contact us](mailto:support@appsignal.com)! ***
\[1] This time does not account for retries of data being transmitted from app servers. Data that has failed to be transmitted, because a server has lost its internet connection for example, will be retried up to 30 minutes by our agent. ↩
# General Data Protection Regulation (GDPR) Source: https://docs.appsignal.com/appsignal/gdpr AppSignal has always had a strong focus on protecting any data we collect and process. As a European owned and operated business we appreciate the solidification of this through the General Data Protection Regulation (GDPR) laws that enter into effect on May 25, 2018. Below you'll read how GDPR applies to AppSignal, our customers and the people our customers collect data from. ## Compliance in relation to our employees and vendors AppSignal B.V. is the entity that owns and operates the AppSignal service, a business located in the Netherlands and therefore bound by Dutch and European law. This entity is fully GDPR compliant, which means we only request and process data based on legal bases as defined in the GDPR. In cooperation with our counsel we have made a thorough assessment of all of our processes and data stores. Where needed, we changed our internal policies and procedures to be in compliance with GDPR, and deleted data that we didn't need or want. We also defined a new Privacy Policy and wrote a Data Processing Agreement (more on that below). Finally, we reached out to our vendors to request agreements to ensure that we remain compliant when using their services. ## Compliance in relation to our customers In relation to our customers, AppSignal is both a Data Controller and a Data Processor depending on the type of data collected. ### Data Controller AppSignal is the Data Controller for the information we collect about our customers and visitors, which means that we determine the "purposes and means" of the data we collect as the Controller. Some examples: their name, their email address, their credit card number, and any other data that we collect based on the GDPR legal bases. This data is safeguarded by various policies and procedures. When sharing data with vendors, we have made sure there are contracts in place that ensure they also receive and process this data in a lawful way. You can read more about the data we collect for which purpose in our new [Privacy Policy](https://www.appsignal.com/privacy-policy). ### Data Processor Our customers are the Data Controllers for the data that their applications gather and send to AppSignal. AppSignal processes that data on behalf of them, which makes us the Data Processor. To enable our customers to be fully GDPR compliant while using AppSignal, we have taken various measures. In short: AppSignal doesn't wish to receive any personal data about your visitors, and will provide the tools that enable you to strip this information before sending it to AppSignal for processing. For more details, see below. #### Data Processing Agreement We have created a Data Processing Agreement that explains eg. how we are a Data Processor, how we limit processing to the level needed to be able to provide the AppSignal service, that we will ensure that our vendors are compliant too, etc (this is an incomplete list for illustrative purposes only; please see the full Data Processing Agreement for all the details). The Data Processing Agreement is accessible to all owners for an organization on AppSignal. Open the Data Processing Agreement for [your organization](https://appsignal.com/redirect-to/organization?to=admin/data_processing_agreements) (there is one for each organization). You can digitally sign the Data Processing Agreement, and once signed we will display who signed it and when. #### Allowed request headers only We have always made sure to strip any personal data from incoming events such as database queries, but we did store request headers such as `REMOTE_ADDR`. Depending on architecture, this can expose useful information about load balancers or internal IP addresses. In most cases though, this sent visitor IP addresses to AppSignal. Since IP addresses are personal data, we have created a default allowlist of headers that we believe will not contain personal data. Customers can add additional headers to the allowlist ([Ruby](/ruby/configuration/options#option-request_headers) / [Elixir](/elixir/configuration/options#option-request_headers)) as needed, as long a they don't identify an individual (eg. if `REMOTE_ADDR` contains the IP address of a load balancer, that's fine). Any non-allowlisted headers are stripped before being sent to AppSignal. #### Filtering options for parameters and session data We've had filtering options for *parameters* for a long time already, but in our [parameter filtering documentation](/application/parameter-filtering) we now stress the importance with regard to GDPR. Recent Ruby gem, Elixir package and Node.js package releases expand this filtering feature to [session data](/application/session-data-filtering) too. It allows customers to send parameters to AppSignal without exposing personal data, by replacing that data with `[FILTERED]`. Alternatively, a customer can choose to not send any parameters ([Ruby](/ruby/configuration/options#option-send_params)) or session data ([Ruby](/ruby/configuration/options#option-skip_session_data) / [Elixir](/elixir/configuration/options#option-skip_session_data) / [Node.js](/nodejs/3.x/configuration/options#option-sendsessiondata))) at all. Data is filtered before being sent to AppSignal. #### Requirements for Tagging We have changed the documentation for our [Tagging](/application/tagging) and [Metadata](/application/metadata) features to strongly state that no personal data should be sent to AppSignal in tags, and that user IDs, hashes or pseudonymized identifiers should be used instead. #### Documentation search (Algolia DocSearch) Our documentation website at docs.appsignal.com uses Algolia DocSearch to provide search functionality. When you use the search, Algolia collects anonymous usage data such as search queries, clicks, and page views to improve search result relevance. Algolia generates an anonymous, ephemeral token for each page visit β€” no cookies are set and no cross-session tracking occurs. This data does not include any personally identifiable information (PII), and is retained for 90 days before being automatically purged. For more information, see [Algolia's privacy policy](https://www.algolia.com/policies/privacy). #### Data removal procedure Any details about a request are stored within what we call "samples". These samples have a retention of 30, 45 or 60 days depending on plan. This has always been the case, but is important with regard to GDPR as well. It means that if any personal data was collected accidentally, it will still be purged after a maximum of 60 days. After that, we only keep aggregated data. If a customer notices that personal data was accidentally sent as part of a sample, we have instated a procedure that allows us to remove one or more samples when requested in an email to [support@appsignal.com](mailto:support@appsignal.com). # How AppSignal integrations operate Source: https://docs.appsignal.com/appsignal/how-appsignal-operates AppSignal consists of many different systems working together. This page will explain what systems are part of the integrations we ship for [Ruby](/ruby) and [Elixir](/elixir), and how they work together. * [Language libraries](#language-libraries) * [Extension](#extension) * [Agent](#agent) * [Working directory](#working-directory) * [Location](#location) * [Permissions](#permissions) ## Language libraries The AppSignal [Ruby gem](https://rubygems.org/gems/appsignal) and [Elixir package](https://hex.pm/packages/appsignal) provide integration for their respective programming language and popular libraries (for [Ruby](/ruby/integrations) and [Elixir](/elixir/integrations)) from its ecosystem, to provide error reporting and performance insights. It is currently required to use one of these libraries to integrate AppSignal into your app and collect [host metrics](/metrics/host-metrics) from its host. When you install the AppSignal Ruby gem and Elixir package in your app, a native [extension](#extension) for the programming language is compiled alongside it. This extension communicates with the [agent](#agent) to efficiently process your data and sent it to the AppSignal [Push API](/appsignal/terminology#push-api). When you boot your application with AppSignal installed, the AppSignal agent will be started in the background. It will only start one agent per configuration, if a new configuration is found a new agent will start and the agents for other versions will be shutdown. ## Extension The AppSignal extension communicates between the programming language and the AppSignal agent. One part is written in Rust and the other in the C programming language. The host machine on which AppSignal is installed therefore need a working [C compiler](https://en.wikipedia.org/wiki/C_%28programming_language%29) present. Usually this is already installed on the host machine, but for a lot of Docker images this is often not the case in order to keep the images small. The required packages for your Operating System are listed on our [supported Operating Systems](/support/operating-systems) page. There are two parts to AppSignal extension, the C-extension and the static/dynamic library written in [Rust](https://www.rust-lang.org/en-US/). The C-extension for [Ruby](https://github.com/appsignal/appsignal-ruby/blob/main/ext/appsignal_extension.c) and the [Nif](/elixir/why-nif) for [Elixir](https://github.com/appsignal/appsignal-elixir/blob/develop/c_src/appsignal_extension.c) will implement the AppSignal library interface so the AppSignal language library can communicate with it. A separate library is used so the implementation can be shared between AppSignal [libraries](#language-libraries). The extension communicates with the agent over a socket, for which the pointer is stored in the agent's [working directory](#working-directory). This communication is one way only, the extension sends the recorded data to the agent and the agent sends this to the AppSignal servers. ## Agent Once started by the [extension](#extension), the AppSignal agent will keep running in the background of your application as a daemonized process. It will handle connections from multiple clients (app processes through the [extension](#extension)) when needed. For example, if you run both Unicorn (web server) and Sidekiq (background job library) at the same time, there will only be one AppSignal agent running for both processes. If the connection to the agent is lost clients will automatically reconnect and/or start a new agent. (Restart behavior added in Ruby gem version `2.4.0`, Elixir package version `1.4.0` and Node.js `1.0.0`). On boot the agent will try to locate a proper [working directory](#working-directory) in which it can store some of its temporary operating files. It needs to create and write files to the working directory and create the `appsignal.log` file before it can boot properly. If it fails to do so, it will not properly boot and exit. The agent requires a location to store the `appsignal.log` file as the `stdout` value for the `log` config option (for [Ruby](/ruby/configuration/options#option-log) and [Elixir](/elixir/configuration/options#option-log)) will not apply to the agent. The agent cannot communicate its logs back over the socket with the extension. The agent itself is a lightweight process written in [Rust](https://www.rust-lang.org/en-US/), that uses very little resources. It only keeps your data in memory for a very short time until it sends it to the AppSignal Push API, after which it flushes the data. If it cannot connect to the AppSignal Push API it will temporarily store the data to disk, see [working directory](#working-directory). Over time the agent will receive monitoring data from your apps and start to aggregate them. After a 30 second transmission interval it will push the aggregated data to the AppSignal Push API. Here it will be processed, incidents and Anomaly detection alerts are created, and eventually notifications are sent to you, the user. Periodically the agent will also read the system stats from the machine its running on to collect [host metrics](/metrics/host-metrics). This is done with help of the [probes-rs](https://github.com/appsignal/probes-rs) library written by AppSignal. The host metrics data is used for the host metrics feature to provide graphs and to show host metrics data for [samples](/appsignal/terminology#samples) at that time. If a request to our [Push API](/appsignal/terminology#push-api) has failed, the payload of that request is written to disk in the [working directory](#working-directory) and it will retry to send the payload at the next transmission interval. ### Working directory The working directory is used for several things that the AppSignal agent needs to keep operating. It's a required part of being able to run the AppSignal agent. If no suitable place for the working directory can be found, the agent will shutdown and the extension in your app will disable itself. It will no longer report any data to the AppSignal servers. The working directory's responsibilities: * `appsignal.log` fallback location * The working directory functions as the fallback location for the `appsignal.log` file when no valid path can be detected and the given `log_path` location is unusable (config option for [Ruby](/ruby/configuration/options#option-log_path) and [Elixir](/elixir/configuration/options#option-log_path)). If not suitable location is found, such as in your project's `log/` directory, it will be stored in `{working_directory}/appsignal.log`. Read more about the [AppSignal logs](/support/debugging#logs). * `agent.socket` file storage * The AppSignal agent stores a socket file in `{working_directory}/agent.socket`, which is used by the AppSignal extension in your application to communicate with the agent. Whenever an AppSignal transaction finishes or you send a custom metric, this data is written to the socket and received by the agent. It will then aggregates this data and transmit it to the AppSignal Push API. * `agent.lock` file storage * The AppSignal agent stores a lock file (`agent.lock`) to ensure there's only one instance of the agent running with your app's configuration. If a new version of the agent is started, older versions will shutdown when they detect a newer version is running, allowing the newly started agent to handle all incoming data from that point on. * Using one working directory, and lock file, for multiple apps running on the same machine this can create some odd behavior. For this reason we recommend using one working directory location per app. Read more about [running multiple applications on one host](/application/#running-multiple-applications-on-one-host). * If you delete this file, or the entire working directory, the agent will shutdown immediately. * `payloads` storage * The payloads directory contains cached payloads written to disk for when the agent is having trouble connecting to our Push API. To avoid the agent's memory footprint increasing over time, this data is stored on disk temporarily. This allows us to make sure we don't lose any of your precious data if your network connection is down for a limited time or our Push API has a small hiccup. The amount of payloads that is stored on disk is automatically limited to the last couple of payloads, so this will always use a small disk space. #### Location The default location of the working directory is `/tmp/appsignal`. If you use a [Capistrano](http://capistranorb.com/) style directory structure it will create a directory named `appsignal` in `app/shared`. On [Heroku](https://heroku.com) style deployments it will create the directory in `/app/tmp`. If neither of these paths are detected, the AppSignal directory will be created in the default location. The location of the working directory can be customized with the `working_directory_path` config option ([Ruby](/ruby/configuration/options#option-working_directory_path) / [Elixir](/elixir/configuration/options#option-working_directory_path)). Any path configured this way will have precedence over any path it can detect. #### Permissions By default the working directly is writable for everyone (Unix permissions `0666`). This is the default, because over time we've seen many support requests that originated from the working directory existing, but not being writable by the AppSignal agent. For example: when the app is started by the deploy user on deploy of the app, but by another user during a host restart. This gives directory ownership to one of the user accounts, while making it unwritable for the other user. It's possible to disable the global read and write permissions (and give the working directory Unix permissions `0644`) by setting the `files_world_accessible` config option ([Ruby](/ruby/configuration/options#option-files_world_accessible) / [Elixir](/elixir/configuration/options#option-files_world_accessible)) to `false` for your apps. # Security overview Source: https://docs.appsignal.com/appsignal/security These are the things we do at AppSignal to keep your data safe. ## Language specific libraries The [Ruby gem](https://github.com/appsignal/appsignal-ruby), [Elixir package](https://github.com/appsignal/appsignal-elixir) and [Node.js package](https://github.com/appsignal/appsignal-nodejs) are public code, hosted on GitHub. You can browse the source to see how we handle the data. Our closed-source [agent](/appsignal/terminology#agent) will send the actual data to the AppSignal servers. We have built several systems to filter or redact sensitive data from reaching our servers, please see the [data collection page](/application/data-collection) for more information. ## System agent With the release of the AppSignal Ruby gem version 1.0 on the 12th of January 2016 we started shipping all our language integrations with a system agent. When an application with AppSignal integration starts the language integration starts a separate UNIX process. The Ruby gem, Elixir package and Node.js package will send all transaction samples to this agent through a UNIX socket. The agent will periodically sends the transaction samples to the AppSignal servers. The system agent will also collect host specific data such as CPU usage, load average, memory usage, disk usage, etc. See the [Host metrics](/metrics/host-metrics) for more information. The data is sent through a secure (SSL) connection to our servers. The code of this system agent is not publicly available, but uses the same basic principle of how our Ruby gem pre `1.0` sends the data to our servers. ## Payment information All payments are handled through [Stripe](https://stripe.com). We do not store or log any credit card information on our servers. The payment provider is PCI compliant, and all credit card and other payment data is also sent over a secure (SSL) connection. ## The AppSignal application AppSignal runs exclusively on secure (SSL) connections and is hosted in a top tier data center. The data center is monitored 24/7, both physically and virtually. Your data is stored redundantly and any sensitive information is stored in separate databases from other customers and long-term data (e.g. graphs). Our systems are kept up-to-date with the latest security patches and our network is locked down with firewalls and limited access. ## Your data All the data we collect from your application is yours and can be retrieved at any point in time through [our API](/api). You can remove your data at any time in the [App Settings](https://appsignal.com/redirect-to/app?to=edit) for your app. ## Incidents If you think you've found a security issue with regards to our application, network or integrations, please let us know immediately by sending an email to [security@appsignal.com](mailto:security@appsignal.com). # Terminology Source: https://docs.appsignal.com/appsignal/terminology At AppSignal we use a lot of technical terms. Read on to learn more about the language of AppSignal. See the list of terminology on the right-hand side of this page. ## Actions Actions are the location in the code where an HTTP request, background job, cron job or task is started. For Ruby on Rails and Elixir's Phoenix apps, this is the controller and action combination, such as `BlogPostsController#create` or `Api::UsersController#index`. For background jobs, this will be the worker/job name, such as `UserMailer#sign_up_mail`. Actions are used to group [issues](#issues) along with the [namespace](#namespace) and [error](#errors). ## Agent AppSignal uses an "agent" to communicate with the AppSignal servers and instrument the hosts an application is running on. The host data is used in our [host metrics](/metrics/host-metrics) feature. The agent is started by the language-specific [library](#libraries) and runs as a separate UNIX process on the application's host. The language library and agent communicate with each other through a UNIX socket using an [extension](#extension). The transaction instrumentation data collected by the agent is sent to the AppSignal servers. The [transaction](#transactions) data is processed and used to detect events worth alerting users about. Read more about how the AppSignal [agent operates](/appsignal/how-appsignal-operates) and the [life cycle of an AppSignal request](/appsignal/data-life-cycle). ## Allocations During an HTTP request or a background job, an application uses memory. Every data structure that's loaded and object that's instantiated takes up memory. When a request or job handles a lot of data a lot more memory may be used than is normal. The AppSignal integration libraries keep track of allocations per [transaction](#transactions). The integration also keeps track of what part of the application allocates more memory objects than others, so it's possible to see if the application's ORM or template library is taking up more memory. On AppSignal.com the number of allocations is displayed in an Integer for an action, event groups and specific events. This allocation number is the number of objects that have been created in memory during an action/group/event. The size of the created object is not tracked. ## Anomaly detection Anomaly detection is an AppSignal feature that allows users to detect abnormalities in their apps. An anomaly could be something like an increased error rate or a limited amount of free memory on the app's host. Anomaly detection works with trigger threshold conditions that create Alerts when their threshold is reached. When an Alert is opened, AppSignal will send notifications to whichever notifiers have been selected for the specific trigger. See our documentation about [Anomaly detection](/anomaly-detection/) for more information. ## API An API is an "Application Programming Interface". The term API is broad and is used in many ways. In the context of our documentation, we refer to the AppSignal HTTP REST API when using "API". The AppSignal API is a HTTP REST API which can be used to retrieve data from the AppSignal servers and augment the existing data with more information such as [Markers](#markers). The API differs from the [Push API](#push-api) in its purpose. While the Push API is used to send data to AppSignal by the [agent](#agent), the HTTP REST API is primarily used to retrieve data from AppSignal. This allows users to use the available data in other tooling. You can read more about our API in our [API documentation](/api). ## API key To connect with the AppSignal [API](#api) it's necessary to be authenticated. Every user has their API key to authenticate with AppSignal. Your API key can be found on your [user profile](https://appsignal.com/users/edit). This key is not to be confused with the [Push API key](#push-api-key) which is used by [applications](#applications) with an AppSignal [agent](#agent) installed. ## Applications Applications (previously known as "sites", also referred to as "apps") are Ruby and Elixir applications monitored by AppSignal. After installing the AppSignal [library](#libraries) in an application AppSignal starts monitoring these applications. Once we receive data from an application, we register it using the application name and environment it's running in. An application can have multiple [environments](#environments) as long as every environment uses the same name. * "Demo application" - Development * "Demo application" - Production * "Demo application" - Staging * "Demo application" - Test Multiple applications can exist in one [organization](#organizations). Read more about applications in our [Applications documentation](/application). ## AppSignal vs Appsignal vs appsignal Wait, they're *three* different casings of the AppSignal name? Yes! Let's explain: | Casing | Usage | | ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `AppSignal` | The brand name of the company, the application and almost everything else related to AppSignal. This is the version you should use when talking about AppSignal as a brand, product or service or [stroopwaffle supplier](#stroopwafels). | | `Appsignal` | The library name of our AppSignal integrations ([Ruby integration](/ruby), [Elixir integration](/elixir), [Node.js integration](/nodejs/3.x/), [Front-end integration](/front-end) etc.). Only used in the code context. | | `appsignal` | The AppSignal integration package names as published to package manager registries for the [Ruby gem](https://rubygems.org/gems/appsignal), [Elixir package and packages prefix](https://hex.pm/packages/appsignal) name, [Node.js packages prefix](https://www.npmjs.com/package/@appsignal/nodejs) and [Front-end packages prefix](https://www.npmjs.com/package/@appsignal/javascript), etc. | ## Blog We have a blog at [blog.appsignal.com](https://blog.appsignal.com/)! On our blog, we post all things relevant to AppSignal, such as new features, new major agent releases, [Ruby Magic](#ruby-magic) articles and other awesome stories from our internal process. Such as [how to eat stroopwafels](https://blog.appsignal.com/blog/2016/02/01/stroopwafels-and-how-to-eat-them.html). ## Changelog We keep a full product changelog at [appsignal.com/changelog](https://www.appsignal.com/changelog). All our new features, agent releases and other changes to the product can be found in this neatly organized list. We also have a small indicator in our top navigation that notifies you if there's a new entry to the changelog. ## Configuration The configuration is part of the libraries running in applications. It tells the AppSignal [libraries](#libraries) what to instrument in an [application](#applications), which application it is and in which environment it's running. The AppSignal libraries have multiple methods of configuration. The most common method of configuration is the usage of an `appsignal.yml` configuration file. The usage of environment variables is also recommended. For the configuration of the Ruby agent, we recommend you read the [configuration topic](/ruby/configuration) to get started. ## CPU usage During the operation of an application, the CPU usage can vary wildly. Some operations of an application can request more CPU time than others. Other factors can also affect the CPU usage. If the monitored application is not the only process on the host machine other processes can also affect the CPU usage metric. For example, if a database running on the same machine has to perform a complicated query it will request more CPU time. On AppSignal.com the CPU usage of an application is displayed in two ways. For an action where an error/performance issue occurred and for host metrics. This way it's possible to see if the performance of an action was directly affected by a busy CPU or if the entire host was affected for longer periods. Learn more about what [CPU metrics](https://blog.appsignal.com/2018/03/06/understanding-cpu-statistics.html) mean on our blog. ## Cross-Site Request Forgery Cross-Site Request Forgery (CSRF) is an attack that forces an end user to execute unwanted actions on a web application where they are authenticated. A victim may click on a link sent to them via email or web chat, allowing the attacker to steal and use the victim's credentials. The severity of the attack can vary depending on the application and authorization access of the victim's account. An attacker may be able to make state-altering actions to a user's account, such as changing their login credentials, and can compromise an entire application in severe cases, such as when a victim is an administrator. ## Elixir Alchemy Want to learn more about Elixir? In our email series Elixir Alchemy (1x p/mo) we dive deeper into Elixir and Erlang. You can sign up here: [appsignal.com/elixir-alchemy](https://blog.appsignal.com/elixir-alchemy). ## Environments Most [applications](#applications) can be run in different modes. During development of an application other rules apply and errors are not usually shown in the form of a "500 internal server error" page as they do in "production". AppSignal also understands the concept of an environment allowing different settings be configured per environment. For every environment a separate application is created on AppSignal.com to be configured with its own set of alerting rules and [third-party integrations](#third-party-integrations). ## Errors Errors are problems that occur during the runtime of an application. This can be anything ranging from a catastrophic failure causing the application to crash or a simple typo causing an error page. Once an error occurs in an application AppSignal sends an alert and records the details of the error for later viewing on AppSignal.com. Read more about the [errors feature](https://www.appsignal.com/tour/errors) on our tour page. To learn more about error handling in Ruby, read our [Exception handling](/ruby/instrumentation/exception-handling) topic describing how to effectively track errors with AppSignal. Errors are reported as issues. Learn more about what [issues](#issues) are. ## Events An event is something that happened. This is a very vague statement because the concept of an event is something very high-level. An [error](#errors) is an event, and so is an [performance issue](#performance-issues). AppSignal monitors many events inside an application and on a server using [host metrics](#metrics). By collecting many different types of events and combining the data we hope to provide an as complete as possible picture to gain more insights into [applications](#applications) performance. Also, see [instrumentation events documentation](#instrumentation-events). ## Extension The AppSignal [libraries](#libraries) and [agent](#agent) are in constant communication with each other. The libraries send data to the agent over a UNIX socket. To do so the libraries use an extension for the programming language they're written in. This extension is written in C and Rust, and installed when the language-specific agent is installed. Read more about the AppSignal [extension operates](/appsignal/how-appsignal-operates) and the [life cycle of an AppSignal request](/appsignal/data-life-cycle). ## Impact The impact of an action on an application is based on its usage compared to other actions. When one controller action or job takes more time or is executed more often than others its impact grows. For example: * Action A is triggered 1000 times with an average duration of 0.5 seconds. The combined duration is 500 seconds. * Action B is triggered 500 times with an average duration of 3 seconds. The combined duration is 1500 seconds. The total combined duration of both actions is 2000 seconds. * Action A has an impact of 25% (500 / 2000). * Action B has an impact of 75% (1500 / 2000). ## Instrumentation Instrumentation is what powers AppSignal. Without it, we wouldn't know anything about what's going on inside Applications. Instrumentation is hooks inside or around frameworks and libraries AppSignal uses to monitor application code. This instrumentation reports errors and slow code which is sent to AppSignal for analysis. Once a problem is detected an alert is sent. Learn more about [Ruby instrumentation](/ruby/instrumentation). ## Instrumentation events Events are blocks of code that are executed. These can be methods, functions or smaller parts of either. Events can be nested to show hierarchy and the total duration of operations. These individual events make it possible to see which parts of the code are slower than others. At the top [issue pages](#issues), we also group the event durations by group name, following [our event naming](/api/event-names), to give insights into what part of the app takes the longest. Some types of events that can be shown are database queries, JSON parsing, views rendering, HTTP requests, [custom instrumentation](#instrumentation), etc. Each event is shown on performance issue detail pages in the "performance timeline". If we detect the same event is repeated more than once in succession, we will mark them as potential N+1 events, such as N+1 queries. Also see [instrumentation](#instrumentation). ## Issues Whenever AppSignal detects a new error, an issue is created. Whenever AppSignal detects a new potential slow request, background job, etc. a new issue is created. This issue is grouped by [action](#actions), [namespace](#namespace) and [error](#errors). Error issues also support errors without action, as an error can occur outside of an action, such as in the app's framework before reaching the app's own code. Performance issues without an [action](#actions) are silently ignored. The action, [namespace](#namespace) and the error type are the way we group issues. If an error of a new type occurs on the same action in the same namespace as another error issue, a new issue will be created for that error. If another potential slow request is detected on another endpoint or background job, a new issue will be created for that endpoint/job. Per issue, it's possible to configure notification settings, assignment, state (open/closed/work in progress), and severity. ## Libraries AppSignal uses language-specific libraries to monitor applications. Currently we have a [Ruby](/ruby) gem and [Elixir](/elixir) package. These libraries include hooks into frameworks and libraries to instrument code blocks such as database calls, file system calls and view rendering. Every library is specialized in the instrumentation of its subject language. Most AppSignal libraries also includes an "[agent](#agent)" which the libraries use to communicate with the AppSignal servers. Read more about how the AppSignal [agent operates](/appsignal/how-appsignal-operates) and the [life cycle of an AppSignal request](/appsignal/data-life-cycle). ### Library integrations AppSignal libraries integrate with a variety of different libraries and frameworks specific to the programming language. The Ruby gem integrates with pure Ruby, Rails, Sinatra and other available frameworks. The Elixir package integrates with pure Elixir and Phoenix. These automatic integrations make it easier to get more insight into applications without having to add AppSignal [instrumentation](#instrumentation) manually. Read more about what [Ruby integrations we offer](/ruby/integrations). ## Markers Markers are little icons used in graphs on AppSignal.com to indicate a change. This can be a code deploy using a "Deploy marker" or a special event with a "Custom marker". These custom markers can be anything from scaling operations, sudden spikes in traffic or when a database is experiencing issues. Read more about [markers](/application/markers). ## Metadata Metadata is data that gives information about other data. Metadata is information about an error or performance issue that provides more context to the data collected. By sending extra metadata on a [sample](#samples) it's easier to track down what the circumstances were around the particular issue. By default the metadata of a request includes the hostname on which the issue occurred, the SCM revision on which the application is running, and the request ID of the request the sample was derived from. It also includes data such as the request path and the request method for web requests. ## Metrics AppSignal provides two kinds of metrics. * [Custom metrics](/metrics/custom) * [Host metrics](/metrics/host-metrics) Custom metrics allow the collection of data from just about anything. With a couple lines of code it's possible to track and graph data such as the number of registered users, visits to a page, database sizes, etc. Host metrics are about data from the server an application is running on. Data such as [CPU usage](#cpu-usage), load averages, memory usage, etc. give more insight into performance issues than just the code itself. Maybe the disk space is running out causing the application to run much slower. Read more about [metrics](https://www.appsignal.com/tour/metrics) on our tour page. ## Namespace Namespaces are grouping mechanisms used by AppSignal to differentiate between different parts of the same application. By default, AppSignal splits an application up into two namespaces: "Web" and "Background". HTTP requests that are being monitored by AppSignal will be added to the "Web" namespace and jobs performed by background job libraries are added to the "Background" namespace. It's also possible to configure your namespaces to differentiate between requests on an application and a private administration panel. For more information about namespaces, please see our [namespaces](/application/namespaces) documentation. ## Notifications AppSignal sends notifications whenever a problem is detected with an [application](#applications). These notifications can be email messages, Slack messages, a PagerDuty notification, and more depending on which [third-party integrations](#third-party-integrations) are configured. We send notifications about [errors](#errors), [slow requests](#performance-issues) and [Anomaly detection](/anomaly-detection/) alerts that occur in an application using an AppSignal [library](#libraries). Once a problematic event is detected a notification is sent out to alert users of a problem. ## Organizations Organizations are used to group [applications](#applications) and [users](#user-account) for a business. A business can have many users and clients that can be notified] whenever there's a problem with their applications. [Billing](/support/billing) for applications is done on organization level rather than per application. [Team management](/organization/team/members) is made easy using organizations. Whole teams can invited to an organization so there's no need for sharing sign-in details. Read more about organizations in our [Organizations documentation](/organization). ## Owners [Organizations](#organizations) have people that manage the organization. These owners decide who's a member of an organization, in which [team](#teams) they do or do not belong and decide how the billing is done. Organization owners can manage everything about an organization and the [applications](#applications) that belong to it. If you do not have permission to view or change something, ask your organization's owner to change it for you or give you more permission. ## Performance issues Using performance monitoring it's possible to deep dive into individual requests and see what parts of an application are slow. Using this information it's possible to find and improve problem areas. When AppSignal detects a slow web request or operation it will send notifications, because slow code can be as damaging as an [error](#errors) appearing. Performance issues are grouped by [action](#actions) and [namespace](#namespace). On performance issue detail pages more information is available about each action. Not all issues are an "issue". It's up to you to determine if an HTTP request of 200ms is too slow. Potential slow requests and background jobs are reported as performance issues. Learn more about what [issues](#issues) are. Read more about the [performance feature](https://www.appsignal.com/tour/performance) on our tour page. ## Push API The AppSignal "Push API" is the API endpoint used by the AppSignal [agent](#agent) to send the collected data. This is different from the normal AppSignal [API](#api) which is primarily used to read data and add more context to the data that's sent to AppSignal. This Push API is the API where application instrumentation is sent from applications using the [Push API key](#push-api-key). ## Push API key The "Push API key" is a write-only API key used by applications to authenticate themselves when sending data to the AppSignal servers. Apps report data to the [Push API](#push-api) and authenticate using this key. There are several kinds of Push API keys that apps can use for different use cases. All Push API keys can be found on the [Push & deploy settings page](https://appsignal.com/redirect-to/app?to=info). * **Organization-level Push API key:** The recommended Push API key for back-end integrations, like Ruby, Elixir, Node.js, Python and Go. We recognize apps by a [combination of the Push API key, app name and app environment](/application/configuration), and create apps using this information if it does not yet exist. * **App-level Push API key:** After creation, an app also gets assigned its app-level Push API key. This key can be used to send data to a specific app, even if the app is configured to use a different app name or app environment. This is used when moving apps between organizations without data loss, or when no app name or app environment can be set, like for the [Vector](/vector) integration. * **Front-end API key:** This key is used by apps using our [front-end integration](/front-end) to report data and can be found in the "Front-end error monitoring" section. Note: These write-only keys are not to be confused with the user-specific [API key](#api-key) which can be used to authenticate on the [AppSignal API](#api) to retrieve data about your apps from our system. ## Response time The response time of an application's action is the time spent processing the action. The longer an action takes to perform the more it qualifies as a performance issue. The duration of this action is displayed on AppSignal.com for performance issues and in graphs for controllers/jobs and on the host level. ## Ruby Magic Did you know we write articles about the magic that is Ruby? We do! It's called Ruby Magic and you can sign up for it on [appsignal.com/ruby-magic](https://blog.appsignal.com/ruby-magic). A list of all the Ruby Magic articles we've written so far can be found on [our blog](https://blog.appsignal.com/). ## Samples When a page request is slow a hundred times in a row, it's not as relevant to see all the slow requests, a smaller sample of these requests tells the same story. Instead, the AppSignal [agent](#agent) only sends a small set of performance issues to the AppSignal servers. This saves data sent to the servers, the data processed on the application host and the AppSignal servers, while still telling the same story about the issues. ## Stroopwafels Also written as "stroopwaffles". At AppSignal, we love stroopwafels. We've shipped over 25,000 of them to customers, friends and conferences. If you work at a tech company and have had a stroopwaffle at the office, chances it came from us. We've written a whole article about what stroopwafels are and how you should eat them. Read on to [become a stroopwafel expert](https://blog.appsignal.com/blog/2016/02/01/stroopwafels-and-how-to-eat-them.html). ## Tags Error and performance issue [samples](#samples) can be tagged. By tagging these samples it's easier to find and identify certain issues. By tagging it's possible to add more [metadata](#metadata) to a sample that can be used in [link templates](/application/link-templates) to easily link to the relevant data in your application. Read more about [tagging requests](/guides/tagging). ## Teams To manage members of [organizations](#organizations), organization owners can utilize teams to give access to applications. [Users](#user-account) that are part of a team can only access the applications the team they belong to have access to. If a user is part of more than one team this user can access all applications of all the teams they belong to. Teams give permission management to [owners](#owners) of an organization to limit user access to applications without the need for multiple organizations. Read more about organization [team management](/organization/team/teams). ## Third-party integrations AppSignal.com provides connections with other services such as Slack and PagerDuty to more effectively alert users about problems that are detected. These integrations can be managed through the UI on AppSignal.com on an application-by-application basis. Read more about [which third-party integrations we offer](/application/integrations/). ## Transactions Transactions are created by the AppSignal [libraries](#libraries) for every monitored web request and background job. Within this transaction, the agents monitor for errors and slow code. A transaction is created at the start of a web request or when a background job is started. Once the request or job finishes or crashes, the transaction is closed and sent to the [agent](#agent) for processing. [Tags](#tags) and [metadata](#metadata) are added on transaction-level to more easily identify differences between transaction samples. ## Throughput The throughput of an application is the total number of requests sent through an action/job in a certain time frame. The throughput can differ per action and host. On AppSignal.com the throughput is displayed per action and displayed in graphs for every host. ## TLS TLS stands for Transport Layer Security. TLS is a cryptographic protocol that provides secure connections for computer networks, for example, between a server and a web browser. ## Queue time When a server or application is busy processing a lot of requests certain requests may be queued before they are processed. The time waiting to be processed is referred to as "queue time". Since queue time can negatively affect users' experience using an application this metric is tracked by AppSignal for HTTP requests and background jobs. For the background jobs, this represents the time between the request being queued (by a web request) and it being picked up by the background worker (sidekiq). ## User account Every user using AppSignal has a user account. With this user account you can configure notification preferences. Many users can belong to one or more organizations. No need for separate user accounts for every organization. [Organizations](#organizations) manage which users can access which applications and who can manage the billing as an [owner](#owners). # Process Monitoring Source: https://docs.appsignal.com/check-ins Learn how to set up and manage AppSignal Process Monitoring AppSignal Process Monitoring provides visibility into the state of background processes such as cron jobs. Process Monitoring helps answer questions like: Once configured, AppSignal will track the execution of background processes and scheduled jobs, giving insights into individual runs and notifying you if a process doesn't notify us of completion. You can configure two kinds of process monitors with AppSignal: **cron process monitors** and **heartbeat process monitors**. Use cron process monitors to track the execution of processes scheduled to run at a specific time, such as cron jobs. Use heartbeat process monitors to track the uptime of a process that should run continuously, such as a server application or a background job processor. ## Getting started First, [create a process monitor in AppSignal](/check-ins/create#create-a-process-monitor), setting the expected schedule for your cron job, or the expected interval between heartbeat process monitor events. For example, you can have a process monitor for a scheduled job that should run every hour for at most 20 minutes, or a background job processor that should report a heartbeat process monitor event at most every 5 minutes. Then, [configure your scheduled job or background process to send process monitor events to AppSignal](/check-ins/configuration). A cron job should send a process monitor event at the start and end of each occurrence, while a background job should send a process monitor event at regular intervals. AppSignal will then [track the process monitor events it receives and compare them to the expected occurrences](/check-ins/occurrences). When AppSignal expects a process monitor event but doesn't receive one in time, it will notify you as configured in the process monitor, helping you ensure that your application's vital processes are working as expected. # Sending process monitor events to AppSignal Source: https://docs.appsignal.com/check-ins/configuration In order to receive events for your AppSignal Process Monitoring, you must configure your application to send process monitor events to AppSignal. ## AppSignal integrations If your application is already using an AppSignal integration library, such as our Ruby gem or our Elixir, Node.js and Python packages, you can use the provided helper methods to send process monitor events. Follow the instructions in the [integration process monitor helpers documentation](/check-ins/configuration/integrations) for your integration. ## Process monitoring with AppSignal Wrap If the application you wish to send process monitors from is not using an AppSignal integration library, for example, if you wish to send cron process monitors when a process starts or finishes, or heartbeat process monitors while a process runs, you can send process monitor events using our wrap tool: ```shell Shell theme={null} appsignal-wrap my-process-name --cron -- /path/to/my/process appsignal-wrap my-process-name --heartbeat -- /path/to/my/process ``` Learn more about how to use `appsignal-wrap` to send process monitors to AppSignal in our [AppSignal Wrap documentation](/wrap#process-monitoring). ## HTTP API You can also send process monitors from any application using our HTTP API. Follow the instructions in the [process monitor events API documentation](/check-ins/configuration/api). # Sending process monitor events using the AppSignal API Source: https://docs.appsignal.com/check-ins/configuration/api Before sending process monitor events to AppSignal, you must first [create a process monitor in AppSignal](/check-ins/create#create-a-process-monitor). You can send process monitor events to AppSignal by performing HTTP POST requests to the AppSignal API, using any HTTP client. The examples in this page provide a sample cURL command, as well as the raw HTTP method and URL to use with any HTTP client of your choice. In the examples below, replace `YOUR-APP-LEVEL-API-KEY` with the AppSignal app-level push API key for your app, which can be found in [your application's "Push & Deploy" settings](https://appsignal.com/redirect-to/app?to=api_keys\&key_tab=app), and `YOUR-PROCESS-MONITOR-IDENTIFIER` with the identifier of the process monitor you wish to send events to. The Process Monitoring API still uses `check_ins` in endpoint URLs for compatibility with existing integrations. ## Sending cron process monitor events Cron process monitors are used to monitor the execution of scheduled jobs, such as cron jobs. AppSignal will expect to receive a finish cron process monitor event according to its configured schedule, and will notify you if no finish cron process monitor event is received within its configured maximum duration. Additionally, you can send start cron process monitor events to AppSignal to notify that a cron process monitor event has started, allowing you to measure the duration of your cron jobs. ### Finish cron process monitor To notify AppSignal that a cron job has finished successfully, send a POST request to the AppSignal API with the following URL query parameters: ```curl Curl theme={null} curl -D - -X POST -G 'https://appsignal-endpoint.net/check_ins/cron' \ -d 'api_key=YOUR-APP-LEVEL-API-KEY' \ -d 'identifier=YOUR-PROCESS-MONITOR-IDENTIFIER' ``` ```http HTTP theme={null} POST https://appsignal-endpoint.net/check_ins/cron ?api_key=YOUR-APP-LEVEL-API-KEY &identifier=YOUR-PROCESS-MONITOR-IDENTIFIER ``` AppSignal will notify you if no finish cron process monitor event is received within the cron process monitor's configured maximum duration. ### Start cron process monitor Sending a start cron process monitor event is entirely optional. Doing so allows you to measure the duration of your cron jobs. To notify AppSignal that a cron job has started, send a POST request to the AppSignal API with the following URL query parameters: ```curl Curl theme={null} curl -D - -X POST -G 'https://appsignal-endpoint.net/check_ins/cron' \ -d 'api_key=YOUR-APP-LEVEL-API-KEY' \ -d 'identifier=YOUR-PROCESS-MONITOR-IDENTIFIER' \ -d 'kind=start' ``` ```http HTTP theme={null} POST https://appsignal-endpoint.net/check_ins/cron ?api_key=YOUR-APP-LEVEL-API-KEY &identifier=YOUR-PROCESS-MONITOR-IDENTIFIER &kind=start ``` #### Sending a digest When sending a start cron process monitor, we recommend sending a digest for both the start and finish events. The digest is an arbitrary value that is used to correlate the start and finish cron process monitor events. It should be the same for both the start and finish events, and it should be unique for each pair of start and finish events. Sending a digest is optional, but it is highly recommended when sending a start cron process monitor event, as it ensures that the start and finish events are correlated correctly. ```curl Curl theme={null} curl -D - -X POST -G 'https://appsignal-endpoint.net/check_ins/cron' \ ... \ -d 'digest=abc123' ``` ```http HTTP theme={null} POST https://appsignal-endpoint.net/check_ins/cron ... &digest=abc123 ``` ## Sending heartbeat process monitor events Heartbeat process monitors are used to monitor the uptime of a process that should run continuously, such as a server application or a background job processor. AppSignal will expect to receive heartbeat process monitor events continuously, and will notify you if no heartbeat process monitor event is received within its configured maximum duration. To send a heartbeat process monitor event to AppSignal, send a POST request to the AppSignal API with the following URL query parameters: ```curl Curl theme={null} curl -D - -X POST -G 'https://appsignal-endpoint.net/check_ins/heartbeats' \ -d 'api_key=YOUR-APP-LEVEL-API-KEY' \ -d 'identifier=YOUR-PROCESS-MONITOR-IDENTIFIER' ``` ```http HTTP theme={null} POST https://appsignal-endpoint.net/check_ins/heartbeats ?api_key=YOUR-APP-LEVEL-API-KEY &identifier=YOUR-PROCESS-MONITOR-IDENTIFIER ``` # Sending process monitor events using the AppSignal integrations Source: https://docs.appsignal.com/check-ins/configuration/integrations The AppSignal integrations for [Ruby](/ruby), [Elixir](/elixir), [Node.js](/nodejs) and [Python](/python) offer helper methods and functions that allow you to easily send process monitor events to AppSignal. The integration helpers still use `CheckIn`, `checkIn`, and `check_in` in code for compatibility with existing applications. ## Cron process monitor events To notify AppSignal that a cron job has finished successfully, use the `cron` helper function, passing the name of the cron process monitor as an argument. ```ruby Ruby theme={null} def send_invoices # ... your code here ... Appsignal::CheckIn.cron("send_invoices") end ``` ```elixir Elixir theme={null} def send_invoices do # ... your code here ... Appsignal.CheckIn.cron("send_invoices") end ``` ```javascript Node.js theme={null} import { checkIn } from "@appsignal/nodejs"; function sendInvoices() { // ... your code here ... checkIn.cron("send_invoices"); } ``` ```python Python theme={null} from appsignal.check_in import cron def send_invoices(): # ... your code here ... cron("send_invoices") ``` It is safe to call the `cron` helper function many times in a short period, as the helper will only send a finish event to AppSignal at most once every ten seconds. ### Monitoring the job's duration To monitor the duration of a cron job, you can use the `cron` helper function with a block or function that contains the code you want to monitor. This will send events to AppSignal both when the job starts and when it finishes. ```ruby Ruby theme={null} def send_invoices() Appsignal::CheckIn.cron("send_invoices") do # ... your code here ... end end ``` ```elixir Elixir theme={null} def send_invoices do Appsignal.CheckIn.cron("send_invoices", fn -> # ... your code here ... end) end ``` ```javascript Node.js theme={null} import { checkIn } from "@appsignal/nodejs"; function sendInvoices() { checkIn.cron("send_invoices", () => { // ... your code here ... }); } // If the function passed to `cron` returns a promise, the finish event // will be reported to AppSignal if the promise resolves, allowing you // to track the duration of async functions: async function sendInvoices() { await checkIn.cron("send_invoices", async () => { // ... your async code here ... }); } // If the promise is rejected, or if it never resolves, the finish event // will not be reported to AppSignal. ``` ```python Python theme={null} from appsignal.check_in import Cron def send_invoices(): with Cron("send_invoices"): # ... your code here ... ``` If an exception is raised within the function or method being monitored, the finish event will not be reported to AppSignal, triggering a missing process monitor notification. The exception will be re-raised. If the context in which the exception is raised is an AppSignal-monitored context, then the exception will be reported to AppSignal. Otherwise, if you wish to report the exception to AppSignal, you can use our exception handling helpers for [Ruby](/ruby/instrumentation/exception-handling#appsignalreport_error), [Elixir](/elixir/instrumentation/exception-handling#appsignalsend_error3), [Node.js](/nodejs/3.x/instrumentation/exception-handling#send-error) or [Python](/python/instrumentation/exception-handling#send_error). ## Heartbeat process monitor events To send a heartbeat process monitor event to AppSignal, use the `heartbeat` helper function, passing the name of the heartbeat process monitor as an argument. It is safe to call `heartbeat` many times, as the helper will only send a heartbeat event to AppSignal at most every ten seconds. ```ruby Ruby theme={null} loop do Appsignal::CheckIn.heartbeat("job_processor") # ... your code here ... end ``` ```elixir Elixir theme={null} def job_processing_loop do Appsignal.CheckIn.heartbeat("job_processor") # ... your code here ... job_processing_loop() end ``` ```javascript Node.js theme={null} import { checkIn } from "@appsignal/nodejs"; while (true) { checkIn.heartbeat("job_processor"); // ... your code here ... } ``` ```python Python theme={null} from appsignal.check_in import heartbeat while True: heartbeat("job_processor") # ... your code here ... ``` ### Sending heartbeats continuously To send heartbeat process monitors continuously, you can pass the `{ continuous: true }` option to the `heartbeat` helper function. This is useful to monitor the lifetime of the process itself. The helper will send a heartbeat event to AppSignal every thirty seconds. ```ruby Ruby theme={null} Appsignal::CheckIn.heartbeat("job_processor", continuous: true) ``` ```elixir Elixir theme={null} # This call spawns a new Elixir process, linked to the current process. # If the current process exits, the heartbeat process will also exit. Appsignal.CheckIn.heartbeat("job_processor", continuous: true) # It is also possible to add a continuous heartbeat sending process # to a supervision tree. This will ensure that the process is restarted # alongside the rest of the supervised children. Supervisor.start_link([ {Appsignal.CheckIn.Heartbeat, "job_processor"}, # ... other children processes ... ], strategy: :one_for_one) ``` ```javascript Node.js theme={null} import { checkIn } from "@appsignal/nodejs"; checkIn.heartbeat("job_processor", { continuous: true }); ``` ```python Python theme={null} from appsignal.check_in import heartbeat heartbeat("my_app", continuous=True) ``` ## Reviewing process monitor occurrences in AppSignal Once configured, AppSignal will begin to display information about occurrences for your process monitors. You can read more about occurrences in our [process monitor occurrences documentation](/check-ins/occurrences). # Creating and managing process monitors Source: https://docs.appsignal.com/check-ins/create ## Create a process monitor To create a process monitor, navigate to the [Process Monitoring page](https://appsignal.com/redirect-to/app?to=check_ins) and click "Add process monitor". On the side, you can select whether to create a cron process monitor or a heartbeat process monitor. The following options can be set: * **Identifier:** A name to uniquely identify this process monitor in your application. You will use this name later when [configuring your application to send process monitor events](/check-ins/configuration). * **Schedule:** The schedule at which AppSignal expects to receive cron process monitor events, specified using crontab syntax. You can learn more about crontab syntax in our [Crontab Learning Center article](https://www.appsignal.com/learning-center/how-can-i-use-the-cron-syntax-to-schedule-cron-jobs). * **Server timezone:** The timezone to use to interpret the cron process monitor schedule. If you're using `cron` to run your scheduled jobs, then this should match your server's configured timezone, as that is the timezone `cron` will use. When in doubt, **we recommend leaving this configuration option on its default value of UTC.** * **Maximum duration:** The maximum run-time of your job in minutes. If a cron process monitor event is not received between the start time determined by the schedule and the end of the maximum job duration, or if a heartbeat process monitor event is not received within this duration from the last heartbeat process monitor event, it will be reported as failing. * **Description:** An optional description of what this process monitor monitors. * **Notify me through:** The channels that AppSignal should use to notify you of any missed or late process monitor occurrences. Screenshot of cron process monitors form For a cron process monitor, a finish process monitor event will be expected for each of the occurrences defined by the schedule, before the maximum duration has passed. For a heartbeat process monitor, heartbeat events will be expected continuously, before the maximum duration since the last heartbeat event has passed. When this expectation isn't met, the process monitor occurrence will be considered failed, and AppSignal will notify you as configured. Once created, you need to [configure your application to send process monitor events](/check-ins/configuration) to AppSignal. ## View all process monitors To view all of your app's process monitors, go to [the process monitors overview page](https://appsignal.com/redirect-to/app?to=check_ins). You can get there from the AppSignal app navigation sidebar: Screenshot of Process Monitoring overview Clicking on the process monitor name will take you to the [process monitor's occurrence overview](/check-ins/occurrences). ### Edit a process monitor To edit a process monitor's settings, navigate to [the process monitors overview page](https://appsignal.com/redirect-to/app?to=check_ins) in the AppSignal app, click on the name of the process monitor you want to change the settings of, then click "Edit" to modify the process monitor's settings. See the [Create a process monitor](#create-a-process-monitor) section for more information on the settings. ### Remove a process monitor To remove a process monitor, click on the name of the process monitor you want to remove, then click "Remove" and follow the on-screen instructions. # Process monitor occurrences Source: https://docs.appsignal.com/check-ins/occurrences You'll be able to begin monitoring your process monitors in AppSignal after: * [Creating a process monitor in AppSignal](/check-ins/create) * [Configuring your application to send process monitors to AppSignal](/check-ins/configuration) A process monitor consists of occurrences which can succeed or fail. For a cron process monitor, an occurrence is a time at which, according to its configured schedule, AppSignal expects to receive a start and finish event for this process monitor. A cron process monitor's occurrence succeeds if it receives a finish event during its maximum duration. For a heartbeat process monitor, an occurrence is a time at which AppSignal has received a heartbeat event, and an occurrence succeeds if it receives another heartbeat event during its maximum duration. ## Viewing process monitors To view all of your app's process monitors, click on the Process Monitoring overview via the AppSignal app navigation: Screenshot of Process Monitoring overview Here, you will have an overview of your process monitors with the following columns: | Column name | Description | | ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Identifier and type | The identifier of your process monitor and its type. | | Schedule | The schedule of your process monitor: the crontab syntax for cron process monitors, or the maximum duration between heartbeats for heartbeat process monitors. | | Last failure | The last time a process monitor occurrence failed. | | Last success | The last time a process monitor occurrence succeeded. | | Last occurrence | The status of the last process monitor occurrence. | ## Statuses The state of a process monitor will be that of its last occurrence. Process monitor occurrences will have one of the following statuses: | Status | Description | | ------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------- | | New | No events have yet been received for this process monitor. | | Success | The process monitor occurrence has been completed within its maximum duration. | | Late | The process monitor occurrence has been completed *after* its maximum duration. | | Missed | The process monitor occurrence has not been completed. | | Running | A start cron process monitor event has been received, or a previous heartbeat's maximum duration has not yet passed. | Late or missed process monitor occurrences are considered to have failed, and AppSignal will notify you that the process monitor has failed according to your process monitor's settings. ## Process monitor summary Clicking on the identifier of a process monitor will take you to an overview of: * **The last five occurrences:** The timestamps for the last five occurrences for the process monitor alongside their status. * **The last five failed occurrences:** The timestamps for the last five missed or late process monitor occurrences. Screenshot of Process Monitoring summary # Wrap process monitoring Source: https://docs.appsignal.com/check-ins/wrap-process-monitoring ## Process Monitoring [Read our Process Monitoring documentation](/check-ins) for more information on how AppSignal Process Monitoring works. By default, `appsignal-wrap` will not send any process monitor events. You can use the `--cron` or `--heartbeat` command-line options to enable cron or heartbeat process monitors respectively. The `appsignal-wrap` tool will use the name provided as the first argument as the process monitor identifier. For example, to report cron process monitor events with `backup-script` as the process monitor identifier: ```sh Shell theme={null} appsignal-wrap backup-script --cron -- bash /var/app/backup.sh ``` ### Cron process monitors When using `--cron` to send cron process monitors, `appsignal-wrap` will send a start cron process monitor event when the process starts, and a finish cron process monitor event if the process finishes successfully. If the process exits with a failure exit status, `appsignal-wrap` will not send a finish cron process monitor event. ### Heartbeat process monitors When using `--heartbeat` to send heartbeat process monitors, `appsignal-wrap` will send heartbeat process monitor events continuously during the lifetime of the process. ### Custom identifier To send process monitor events to AppSignal with an identifier different from the name provided as the first argument, you can pass a different identifier as an argument to the `--cron` or `--heartbeat` command-line options. For example: ```sh Shell theme={null} appsignal-wrap backup --cron daily-backup -- bash /var/app/backup.sh ``` In the above example, `appsignal-wrap` will send cron process monitor events with `daily-backup` as the process monitor identifier, but will still use `backup` as the name to identify the process when reporting logs and errors. # AppSignal CLI Source: https://docs.appsignal.com/cli Query your AppSignal data from the terminal: tail logs, inspect incidents, and manage triggers without leaving your shell. The AppSignal CLI brings your monitoring data into the terminal, so you can work from the same shell where you run your tests and deploys. Tail logs as they arrive, search incidents and close them out, and manage anomaly detection triggers, all without opening the web UI. It's a single binary built in Rust, so there's nothing else to install. The CLI is built for two kinds of users: people and AI agents. By default every command prints human-readable output; pass `--output json` and it returns machine-readable JSON instead. In other words, the same tool you reach for during an incident can also feed structured data to a coding agent. It even bundles an [AppSignal agent skill](/cli/skill): a set of instructions that teaches an agent like Claude or Codex how to use the CLI. Install it with `appsignal-cli skill install`. The CLI talks to the same AppSignal data as the app UI and [AppSignal MCP](/mcp-server). It's a gateway to data AppSignal already has. If your app isn't sending logs, `logs tail` won't show any. ## What you can do * **Logs:** tail log lines as they arrive, or search across a time range with AppSignal's [query syntax](/logging/query-syntax). Filter by severity or source, apply saved log views, and list an app's views and sources. Create and manage log-derived metrics and log-based triggers from your log data. * **Incidents:** list exception, performance, and anomaly incidents, and search the exception and performance ones by name or message; open an incident's details; update its state, severity, or assignees; and add notes. * **Triggers:** list, create, update, and archive anomaly detection triggers. * **Dashboards:** list, create, and update your app's [dashboards](/cli/dashboards). * **Apps:** list your applications, find an app by name, and inspect its users, notifiers, namespaces, dashboards, and deploy markers. * **Project configuration:** create a [project-local config](/cli/configuration) so commands run in a repository default to the right organization. * **Agent skill:** install the bundled AppSignal skill into your AI agent, update it, and check whether it's current. ## Global flags These flags work on every command: | Flag | Description | | ------------------------- | ----------------------------------------------------------------------------------------------------- | | `--output ` (`-o`) | Render results as `human` (the default) or `json`. `--format` is a synonym. | | `--help` (`-h`) | Show usage, subcommands, and options for any command (for example, `appsignal-cli logs tail --help`). | You can pass `--output` (or `--format`) before or after the subcommand. Command results go to standard output in the format you choose; status messages always go to standard error, so a `--output json` stream stays valid JSON that you can pipe into another tool. ## Installation The CLI runs on macOS and Linux, on both Intel (`x86_64`) and Apple Silicon / ARM (`arm64`) machines. Linux distributions based on musl, such as Alpine, are supported too. Install the formula. Homebrew taps `appsignal/appsignal-cli` automatically: ```sh theme={null} brew install appsignal/appsignal-cli/appsignal-cli ``` To upgrade later, run: ```sh theme={null} brew upgrade appsignal-cli ``` Install the latest release with the one-liner below. It needs super-user privileges to install the binary on your system path, and verifies the download against the published `SHA256SUMS` manifest before installing: ```sh theme={null} curl -sSL https://github.com/appsignal/appsignal-cli/releases/latest/download/install.sh | sudo sh ``` Re-run the same command at any time to update to the latest release. Prefer not to pipe a script into your shell? Download the binary for your platform directly from the [latest release](https://github.com/appsignal/appsignal-cli/releases/latest/). ### Verify the installation Check that the CLI is on your `PATH`: ```sh Shell theme={null} appsignal-cli --version ``` Then run `appsignal-cli about` for an overview of your setup, including its version, endpoint, default organization, and authentication status: ```sh Shell theme={null} appsignal-cli about ``` Before you authenticate, it'll show `Auth: Not authenticated` and point you at the commands to run next. ## Next steps You've installed the CLI, but it can't reach your data until you sign in. Head to [Authentication](/cli/authentication) to connect the CLI to your AppSignal account. # Apps and organizations Source: https://docs.appsignal.com/cli/apps Find and inspect your applications from the terminal, set a default organization, and view an app's users, namespaces, dashboards, and deploy markers. Most CLI commands act on a single application in a single environment, so before you tail logs or list incidents, you need to know which apps you have and how to name them. This page covers listing your applications, setting a default organization, and inspecting an app's resources. ## Organizations Your applications live under an organization, identified by its slug: the short name in your AppSignal URL, `appsignal.com/`. The CLI works with the organization tied to your signed-in account. ### Set a default organization Most commands fall back to a default organization, so you don't need to pass `--org` every time. Running `appsignal-cli apps list` determines your account's organization and saves it as the default. To set or change it yourself: ```sh Shell theme={null} appsignal-cli apps set-org --org ``` To see the current default: ```sh Shell theme={null} appsignal-cli apps show-org ``` You can also set the default during sign-in with `appsignal-cli auth login --org `, or per project with `appsignal-cli project init --org `. See [Authentication](/cli/authentication) for how the global and project-local configs relate. ## Applications To list the applications for your account's organization: ```sh Shell theme={null} appsignal-cli apps list ``` This also saves your organization as the default for later commands, so you don't need to pass `--org` to them. ### Find an app by name To look up a specific app by name, optionally narrowing to one environment: ```sh Shell theme={null} appsignal-cli apps find --name "MyApp" --environment production ``` The name and environment are both case-insensitive. This is the quickest way to confirm the exact app name and environment that other commands expect. ### Show details for an app If you know an app's ID, you can fetch its details directly: ```sh Shell theme={null} appsignal-cli apps info --app-id ``` ## How commands identify an app Commands that act on a single app accept it in one of two ways: * **By name:** `--app "MyApp"`. Add `--environment production` only when more than one app shares the name. * **By ID:** `--app-id `, the value from the `ID` column of `appsignal-cli apps list` (a long hexadecimal string). An ID identifies a specific app and environment on its own, so you don't pass `--environment` with it. Use whichever you have. A name is easier to read and type; the ID is unambiguous and convenient in scripts. ## Inspect an app's resources The `apps resources` commands show the configuration and metadata attached to an app: | Command | Shows | | ------------------------------- | --------------------------------- | | `apps resources all` | Every resource below, in one call | | `apps resources users` | Users with access to the app | | `apps resources notifiers` | Configured notifiers | | `apps resources namespaces` | The app's namespaces | | `apps resources dashboards` | Custom dashboards | | `apps resources deploy-markers` | Recent deploy markers | Each takes the same app selector as other commands, either `--app` with `--environment` or `--app-id`, and uses your default organization unless you pass `--org`. For example, to see the namespaces for an app: ```sh Shell theme={null} appsignal-cli apps resources namespaces --app "MyApp" --environment production ``` To pull everything at once as JSON, for feeding into another tool: ```sh Shell theme={null} appsignal-cli apps resources all --app "MyApp" --environment production --output json ``` ## Next steps Once you know an app's name and environment, you can start querying it. Inspect its [incidents](/cli/incidents) or tail its [logs](/cli/logs) from the terminal. # Authentication Source: https://docs.appsignal.com/cli/authentication Sign in to the AppSignal CLI with OAuth, and manage where your credentials are stored. Before the CLI can reach your data, you need to sign in. It uses OAuth, a browser-based sign-in, so you never have to copy or store a token by hand. You can check whether you're signed in at any time with `appsignal-cli auth status`. ## Sign in Run: ```sh Shell theme={null} appsignal-cli auth login ``` This opens your browser to authorize the CLI with your AppSignal account, then hands control back through a local callback on `http://127.0.0.1:9789/callback`. Once you approve, the CLI stores the tokens and refreshes them for you, so you won't have to sign in again. The browser flow needs a browser on the same machine as the CLI. ## Set a default organization If you belong to more than one organization, set a default while you sign in, so you don't have to pass it on every command: ```sh Shell theme={null} appsignal-cli auth login --org ``` Your organization slug is the short name in your AppSignal URL: `appsignal.com/`. Running `appsignal-cli apps list` after you sign in also saves your account's organization as the default. ## Check your status To see whether you're signed in, and which config the CLI is reading, run: ```sh Shell theme={null} appsignal-cli auth status ``` `appsignal-cli about` shows the same authentication status alongside your version, endpoint, and default organization. ## Sign out To remove your stored credentials: ```sh Shell theme={null} appsignal-cli auth logout ``` ## Where your credentials live The CLI stores your credentials in a global config file, in your operating system's standard config directory. The exact location varies by OS, so run `appsignal-cli auth status` to see the path the CLI is using. ### Project-local configuration You can also keep configuration alongside a project, in an `.appsignal.toml` file in the project directory. Create one with: ```sh Shell theme={null} appsignal-cli project init ``` A project-local config is handy for pinning a repository to a specific organization. To set the default organization for the project as you create it: ```sh Shell theme={null} appsignal-cli project init --org ``` When a project-local `.appsignal.toml` is present, the CLI uses the nearest one as the only config for commands run in that directory or its subdirectories. For the full list of config keys and how they resolve, see [Configuration](/cli/configuration). `project init` doesn't copy your global OAuth credentials into the project config. After creating it, run `appsignal-cli auth login` again inside the project to set up project-specific credentials. ## Next steps You're signed in. Next, [list your applications](/cli/apps) to find the apps you'll be querying. # Configuration Source: https://docs.appsignal.com/cli/configuration How the AppSignal CLI stores its settings: the project command, the global and project-local config files, and every config key. The CLI reads its settings from a TOML config file. There are two kinds: a global config tied to your account, and an optional project-local `.appsignal.toml` that takes over inside a project. This page covers the `project` command, where each file lives, and every key you can set. ## The `project` command `appsignal-cli project init` creates or updates a project-local `.appsignal.toml`: ```sh Shell theme={null} appsignal-cli project init ``` If you run it inside a git checkout, the CLI writes `.appsignal.toml` at the repository root. Outside a git checkout, it uses the current directory. You can set the project's default organization as you create the file: ```sh Shell theme={null} appsignal-cli project init --org ``` `project init` accepts these flags: | Flag | Description | | ------------------------ | ----------------------------------------------------------------- | | `--org ` | Set the default organization for the project | | `--endpoint ` | Point the project at a non-production AppSignal server | | `--rest-endpoint ` | Point the project at a non-production REST or public API base URL | | `--oauth-client-id ` | Override the OAuth client ID for the project | `project init` doesn't copy your global OAuth credentials into the project file. After creating it, run `appsignal-cli auth login` inside the project to set up project-specific credentials. Don't commit `.appsignal.toml` to version control. Once you authenticate, it holds your OAuth tokens. Add it to your `.gitignore`. ## Where config lives The global config lives in your operating system's standard config directory; its exact path varies by OS. Run `appsignal-cli auth status` to see where yours is. It holds your account-wide credentials and default organization. A project-local `.appsignal.toml` can live anywhere in a project. When the CLI runs inside that project or a subdirectory, it uses the nearest `.appsignal.toml` as the only config for that project. When a project-local config is active, the CLI reads and writes only that file. Otherwise, it uses the global config. The `org` value is saved automatically when you run `appsignal-cli apps list` or `appsignal-cli apps set-org --org `, into whichever config is active. Run `project init` first if you want those writes to stay local to the project. ## Config keys Both files use the same keys: | Key | Description | | --------------- | ------------------------------------------------------------------------------------------------------------------- | | `org` | Default organization slug, used when a command omits `--org`. | | `[oauth]` table | OAuth credentials (`access_token`, `refresh_token`, `expires_at`). Set automatically by `appsignal-cli auth login`. | A global config looks like this: ```toml Global config theme={null} org = "" # Set automatically by `auth login`: [oauth] access_token = "..." refresh_token = "..." expires_at = 1742324400 ``` A project-local `.appsignal.toml` uses the same format. OAuth tokens are refreshed automatically before API calls, so you don't have to sign in again. OAuth always uses the built-in local callback at `http://127.0.0.1:9789/callback`. ## Telemetry The CLI sends a minimal, best-effort telemetry event for each command run, to help AppSignal measure CLI usage and reliability. Each event includes only the command path, whether it succeeded or failed, how long it took, the CLI version, and the output format. It contains none of your AppSignal data. To turn it off, set `APPSIGNAL_CLI_TELEMETRY=0`: ```sh Shell theme={null} APPSIGNAL_CLI_TELEMETRY=0 appsignal-cli incidents list --app "MyApp" --environment production ``` Set the variable in your shell profile to disable telemetry for every command. ## Custom endpoints Most users never need these settings. They make the CLI talk to a non-production AppSignal server instead of the default, which is mainly useful to AppSignal's own engineers for testing. You can set them as flags on `project init` or `auth login`, or as keys in your config file. The keys are: | Config key | Description | | ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `endpoint` | Base URL of the AppSignal server, without `/graphql`. The CLI appends `/graphql` for API calls and uses the base URL for OAuth. | | `rest_endpoint` | Base URL of the REST or public API, when it differs from `endpoint`. | | `oauth_client_id` | OAuth client ID to use during login. When unset, the CLI uses the production client, or registers one automatically for endpoints that advertise a `registration_endpoint`. | A value like `https://appsignal.example.com/graphql` is not supported. Use the base URL only. ## Next steps With your configuration in place, [list your apps](/cli/apps) and start querying your data. # Dashboards Source: https://docs.appsignal.com/cli/dashboards List, create, and update an app's dashboards from the terminal. The `dashboards` command manage an app's dashboards from the terminal: list the existing ones, create a dashboard, and update a dashboard's title or description. Each command targets one application, by name and environment (`--app "MyApp" --environment production`) or by ID (`--app-id `, the long hexadecimal app ID from `appsignal-cli apps list`). The `--environment` flag is only needed when several apps share a name. Each command uses your default organization unless you pass `--org`. See [Apps and organizations](/cli/apps) for how apps are identified. ## List dashboards ```sh Shell theme={null} appsignal-cli dashboards list --app "MyApp" --environment production ``` The list includes each dashboard's ID, which you need to update one. ## Create a dashboard A new dashboard needs a title, and can take an optional description: ```sh Shell theme={null} appsignal-cli dashboards create --app "MyApp" --environment production \ --title "Checkout health" --description "Latency and error rate for checkout" ``` | Flag | Description | | ---------------------- | ------------------------------------------------------------------------------------------ | | `--title ` | Dashboard title (required) | | `--description <text>` | Optional description | | `--app <name>` | App to create the dashboard in (add `--environment` when the name isn't unique) | | `--environment <env>` | Environment, used with `--app` | | `--app-id <id>` | The app's ID (a long hexadecimal string), as an alternative to `--app` and `--environment` | | `--org <slug>` | Organization slug (uses your default if omitted) | ## Update a dashboard Pass the dashboard's `--id` (from `dashboards list`) along with the new title: ```sh Shell theme={null} appsignal-cli dashboards update --id <DASHBOARD_ID> --app "MyApp" --environment production \ --title "Checkout health" --description "Updated description" ``` | Flag | Description | | ---------------------- | ------------------------------------------------------------------------------------------ | | `--id <id>` | ID of the dashboard to update (required; from `dashboards list`) | | `--title <title>` | New title (required) | | `--description <text>` | Optional description | | `--app <name>` | App the dashboard belongs to (add `--environment` when the name isn't unique) | | `--environment <env>` | Environment, used with `--app` | | `--app-id <id>` | The app's ID (a long hexadecimal string), as an alternative to `--app` and `--environment` | | `--org <slug>` | Organization slug (uses your default if omitted) | `--title` is required even when you only change the description. ## Next steps A dashboard visualizes your metrics. To get alerted when one crosses a threshold, set up [anomaly detection triggers](/cli/triggers). # Incidents Source: https://docs.appsignal.com/cli/incidents List, search, inspect, and triage exception, performance, and anomaly incidents from the terminal. The CLI lets you work through incidents without opening the web UI. You can list incidents across all types or by type, narrow them by state, namespace, or action, open a single incident's details, update its state or severity, and add notes. Every `incidents` command targets one application, identified either by name and environment (`--app "MyApp" --environment production`) or by ID (`--app-id <APP_ID>`, the long hexadecimal app ID from `appsignal-cli apps list`). The `--environment` flag is only needed when several apps share a name. Add `--org` to override your default organization. See [Apps and organizations](/cli/apps) for how apps are identified. ## List incidents To list recent incidents of all types for an app: ```sh Shell theme={null} appsignal-cli incidents list --app "MyApp" --environment production --limit 5 ``` By default, the list commands return the 10 most recent incidents, ordered by most recent activity. ### List by type Three commands narrow the results to a single incident type: ```sh Shell theme={null} # Exception incidents appsignal-cli incidents list-exceptions --app "MyApp" --environment production # Performance incidents appsignal-cli incidents list-performance --app "MyApp" --environment production # Anomaly detection incidents appsignal-cli incidents list-anomalies --app "MyApp" --environment production ``` ## Filter and search The list commands share a set of filters: | Flag | Description | | ----------------- | --------------------------------------------------------------------------- | | `--state <STATE>` | Filter by state: `OPEN`, `CLOSED`, or `WIP` | | `--order <ORDER>` | Sort by `LAST` (most recent activity, the default) or `ID` (creation order) | | `--limit <N>` | Maximum results (default: 10) | | `--offset <N>` | Number of results to skip, for paging | `incidents list`, `list-exceptions`, and `list-performance` also accept: | Flag | Description | | --------------------- | ------------------------------------------------------------- | | `--namespaces <list>` | Filter by namespaces, comma-separated (e.g. `web,background`) | | `--action <name>` | Filter by action name (e.g. `UsersController#show`) | Exception and performance incidents support a text search over the incident name or message with `--query`: ```sh Shell theme={null} appsignal-cli incidents list-exceptions --app "MyApp" --environment production --query "TimeoutError" ``` You can pass several filters in one command, and they all apply together to narrow the results. For example, list only the open exceptions in the `web` namespace: ```sh Shell theme={null} appsignal-cli incidents list-exceptions --app "MyApp" --environment production \ --state OPEN --namespaces web ``` <Note> The list commands return recent incidents, so older ones may not appear even when they're still open. To open a specific incident regardless of age, use `incidents show` with its number. </Note> ## Show an incident To see the full details of a single incident, pass its number: ```sh Shell theme={null} appsignal-cli incidents show --number 42 --app "MyApp" --environment production ``` ## Update an incident Update an incident's state, severity, assignees, or description by number: ```sh Shell theme={null} appsignal-cli incidents update --number 42 --app "MyApp" --environment production --state CLOSED ``` | Flag | Description | | --------------------------- | -------------------------------------------------------------------------------- | | `--state <STATE>` | New state: `OPEN`, `CLOSED`, or `WIP` | | `--severity <SEV>` | New severity: `UNTRIAGED`, `CRITICAL`, `HIGH`, `LOW`, `NONE`, or `INFORMATIONAL` | | `--assign <NAMES_OR_IDS>` | User names or IDs to add as assignees, comma-separated | | `--assign-me` | Assign the incident to your authenticated user | | `--unassign <NAMES_OR_IDS>` | User names or IDs to remove from assignees, comma-separated | | `--description <text>` | New description | To change several incidents at once, pass a comma-separated list of numbers. Bulk updates currently support `--state` only: ```sh Shell theme={null} appsignal-cli incidents update --number 41,42,43 --app "MyApp" --environment production --state CLOSED ``` ### Assign an incident To assign an incident to yourself, use `--assign-me`. It needs no user ID: ```sh Shell theme={null} appsignal-cli incidents update --number 42 --app "MyApp" --environment production --assign-me ``` To assign other people, pass their names or user IDs to `--assign`, comma-separated. A user ID is a long hexadecimal string. Find names and IDs with [`apps resources users`](/cli/apps), which lists each user's name, ID, and email: ```sh Shell theme={null} appsignal-cli apps resources users --app "MyApp" --environment production ``` Then pass one or more to `--assign`: ```sh Shell theme={null} appsignal-cli incidents update --number 42 --app "MyApp" --environment production \ --assign <NAME_OR_ID> ``` To remove assignees, pass their names or IDs to `--unassign` the same way. ## Add a note To record what you found on an incident: ```sh Shell theme={null} appsignal-cli incidents add-note --number 42 --app "MyApp" --environment production \ --content "Root cause identified." ``` ## JSON output Like every command, the incidents commands accept the global `--output json` (or `--format json`) flag, which returns machine-readable output for scripts and AI agents: ```sh Shell theme={null} appsignal-cli --output json incidents list-exceptions --app "MyApp" --environment production --state OPEN ``` To return a single incident as JSON, narrow by its number with `incidents show`: ```sh Shell theme={null} appsignal-cli --output json incidents show --number 42 --app "MyApp" --environment production ``` ## Next steps Incidents tell you what's failing. To see the surrounding log lines, [tail or search your logs](/cli/logs) from the terminal. # Logs Source: https://docs.appsignal.com/cli/logs Tail and search application logs from the terminal, and manage log-derived metrics and log-based triggers. The `logs` command bring your application logs into the terminal: tail them as they arrive, search across a time range, and manage the log-derived metrics and log-based triggers built from them. ## Common options Every `logs` command identifies one application, and uses your default organization unless you tell it otherwise: | Flag | Description | | --------------------- | --------------------------------------------------------------------------------------------------------------- | | `--app <name>` | Application name (add `--environment` when more than one app shares the name) | | `--environment <env>` | Environment, used with `--app` | | `--app-id <id>` | The app's ID (a long hexadecimal string from `appsignal-cli apps list`), instead of `--app` and `--environment` | | `--org <slug>` | Organization slug (uses your default if omitted) | ## Tail logs Stream log lines as they arrive (the CLI polls every second): ```sh Shell theme={null} appsignal-cli logs tail --app "MyApp" --environment production ``` ## Search logs Search past log lines and print the matches. For example, find recent error-level lines: ```sh Shell theme={null} appsignal-cli logs search --app "MyApp" --environment production --query "severity:error" ``` By default, `search` returns up to 100 of the most recent matches. On top of the common options and filters, it adds: | Flag | Description | | ------------------- | ----------------------------------------------------------------------------------------------- | | `--start <ISO8601>` | Start time, e.g. `2025-01-01T00:00:00Z` | | `--end <ISO8601>` | End time | | `--limit <N>` | Maximum lines to return (max 100, also the default) | | `--order <ORDER>` | `ASC` (oldest first) or `DESC` (newest first, the default) | | `--page-all` | Fetch every matching line in the range. Requires `--start`, and ignores `--limit` and `--order` | To pull every line in a window as JSON, for a script or agent: ```sh Shell theme={null} appsignal-cli --output json logs search --app "MyApp" --environment production \ --start "2025-01-01T00:00:00Z" --query "severity:error" --page-all ``` ## Filters `tail` and `search` share these filters: | Flag | Description | | --------------------- | ------------------------------------------------------------------------- | | `--query <text>` | Log query filter, using AppSignal's [query syntax](/logging/query-syntax) | | `--severities <list>` | Comma-separated severities, e.g. `ERROR,CRITICAL` | | `--source-ids <list>` | Comma-separated source IDs | | `--view <name-or-id>` | Apply a saved log view's filters as defaults | List the views available for an app with `appsignal-cli logs views`, then pass one to `--view` by name or ID. Any other filters you add override the view's saved defaults. For example, apply a view but narrow it to critical lines: ```sh Shell theme={null} appsignal-cli logs search --app "MyApp" --environment production \ --view "Production errors" --severities CRITICAL ``` ### Query syntax The `--query` flag uses AppSignal's [log query syntax](/logging/query-syntax). Common patterns: * `severity=error`: exact field match * `message:timeout`: message contains "timeout" * `group=notifiers`: exact group match * `hostname:web-1`: hostname contains "web-1" * Space-separated terms combine with `AND`; use `OR` for alternatives Square brackets have special meaning in the parser, so quote them to match literally: `message:"[Email]"`. ## Saved views and sources List an app's saved log views (filter presets) and its log sources: ```sh Shell theme={null} appsignal-cli logs views --app "MyApp" --environment production appsignal-cli logs sources --app "MyApp" --environment production ``` Pass a view's name or ID to `--view`, and a source's ID to `--source-ids`. ## Log-derived metrics `logs metrics` turns matching log lines into metrics, with `list`, `create`, `update`, and `delete`: ```sh Shell theme={null} appsignal-cli logs metrics create --app "MyApp" --environment production \ --name "Checkout latency" \ --query "group:checkout" \ --metric "name=log.checkout_duration_ms,type=distribution,field=duration_ms" \ --source-id <SOURCE_ID> ``` `create` and `update` share these flags (`create` requires `--name`, `--query`, and at least one `--metric`): | Flag | Description | | ------------------ | ----------------------------------------------------------------------------------------------------- | | `--name <name>` | Metric configuration name | | `--query <text>` | Query matching the log lines to measure | | `--metric <def>` | Metric definition in `key=value` form (repeat for multiple), e.g. `name=log.error_count,type=counter` | | `--source-id <id>` | Scope to a source ID (repeat for more) | `update` can take the following additional flags. The `--clear-*` flags empty fields instead of updating them. | Flag | Description | | ----------------- | --------------------------------------------------------- | | `--id <id>` | The metric to update, from `logs metrics list` (required) | | `--clear-metrics` | Remove all metric definitions | | `--clear-sources` | Remove all source scoping | `delete` takes only `--id`. <Note> A log-derived metric only starts collecting data once it's scoped to a log source, so pass `--source-id` (find IDs with `appsignal-cli logs sources`). The CLI can't set a metric's severity filter; if your metric needs one, set the Severity field in the AppSignal app UI after creating it. </Note> ## Log-based triggers `logs triggers` alerts on matching log lines, with `list`, `create`, `update`, and `delete`: ```sh Shell theme={null} appsignal-cli logs triggers create --app "MyApp" --environment production \ --name "Root login" \ --query "message:root" \ --severity ERROR \ --notifier-id <NOTIFIER_ID> ``` `create` and `update` share these flags (`create` requires `--name` and `--query`): | Flag | Description | | ---------------------- | --------------------------------------------- | | `--name <name>` | Trigger name | | `--query <text>` | Query matching the log lines to alert on | | `--severity <level>` | Match only these severities (repeat for more) | | `--notifier-id <id>` | Attach a notifier (repeat for more) | | `--source-id <id>` | Scope to a source ID (repeat for more) | | `--description <text>` | Trigger description | `update` can take the following additional flags. The `--clear-*` flags empty fields instead of updating them. | Flag | Description | | --------------------- | ----------------------------------------------------------- | | `--id <id>` | The trigger to update, from `logs triggers list` (required) | | `--clear-description` | Remove the description | | `--clear-notifiers` | Remove all notifiers | | `--clear-severities` | Remove all severities | | `--clear-sources` | Remove all source scoping | `delete` takes only `--id`. <Note> These are log-based triggers, built from log lines. For anomaly detection triggers on metrics, see [Triggers](/cli/triggers). </Note> ## Next steps Found something in the logs? Open the related [incidents](/cli/incidents), or set up [anomaly detection triggers](/cli/triggers). # Agent skill Source: https://docs.appsignal.com/cli/skill Install the bundled AppSignal skill into Claude, Codex, or OpenCode so your AI coding agent can drive the CLI. The CLI bundles an AppSignal agent skill: a set of instructions that teaches an AI coding agent how to use `appsignal-cli` to inspect your AppSignal data. Installing it writes a `SKILL.md` into the agent's skills directory, so the agent knows when to reach for the CLI and how to read its JSON output. <Note> The skill teaches an agent to run the CLI, so the agent acts as you. Make sure the CLI is [authenticated](/cli/authentication) on the machine where the agent runs. </Note> ## Install the skill ```sh Shell theme={null} appsignal-cli skill install ``` By default this installs the skill for OpenCode. Choose a different agent, or install for all of them, with `--target`: ```sh Shell theme={null} # Claude appsignal-cli skill install --target claude # Codex appsignal-cli skill install --target codex # Every supported agent appsignal-cli skill install --target all ``` ### Supported agents Each target installs the same skill into that agent's default skills directory: | Target | Installs to | | ------------------------ | ------------------------------------------------------------------------------------------------------------ | | `opencode` (the default) | `~/.agents/skills/appsignal/SKILL.md` | | `codex` | `$CODEX_HOME/skills/appsignal/SKILL.md`, or `~/.codex/skills/appsignal/SKILL.md` when `$CODEX_HOME` is unset | | `claude` | `~/.claude/skills/appsignal/SKILL.md` | | `all` | All of the directories above | Two more flags adjust where and how the skill is installed: | Flag | Description | | -------------- | ----------------------------------------------------------------------- | | `--dir <path>` | Install into this skills root directory instead of the target's default | | `--force` | Overwrite an existing installed skill | `skill update` and `skill status` accept the same `--target` and `--dir` flags, so you can update or check a skill installed in a custom location. ## Keep the skill up to date An installed skill records the CLI version that produced it. After you upgrade `appsignal-cli`, refresh your installs to the bundled version: ```sh Shell theme={null} appsignal-cli skill update ``` Like `install`, `update` acts on OpenCode by default; pass `--target` to update a different agent or `all` of them. ```sh Shell theme={null} appsignal-cli skill update --target all ``` ## Check installation status To see whether your installed skills are current, outdated, or missing: ```sh Shell theme={null} appsignal-cli skill status ``` `status` checks all supported agents by default, so you get one list covering OpenCode, Codex, and Claude. Pass `--target` to narrow it to a single agent. ## Next steps The skill lets an agent run the CLI from your shell. For agents that talk to AppSignal directly over HTTP instead, see [AppSignal MCP](/mcp-server). # Triggers Source: https://docs.appsignal.com/cli/triggers List, create, update, and archive anomaly detection triggers from the terminal. The `triggers` commands manage anomaly detection triggers: alerts that fire when a metric crosses a threshold you define. Each command targets one application, by name and environment (`--app "MyApp" --environment production`) or by ID (`--app-id <APP_ID>`, the long hexadecimal app ID from `appsignal-cli apps list`). The `--environment` flag is only needed when several apps share a name, and each command uses your default organization unless you pass `--org`. See [Apps and organizations](/cli/apps). <Note> These are anomaly detection triggers on metrics. For triggers built from log lines, see [Logs](/cli/logs). </Note> ## List triggers ```sh Shell theme={null} appsignal-cli triggers list --app "MyApp" --environment production ``` ## Create a trigger A trigger watches one metric field and opens an alert when it crosses a threshold: ```sh Shell theme={null} appsignal-cli triggers create --app "MyApp" --environment production \ --name "Slow web requests" \ --metric-name response_time --kind Advanced --field mean \ --comparison-operator ">" --condition-value 500 \ --warmup-duration 5 --cooldown-duration 2 \ --description "Alert when mean response time stays above 500ms" ``` These flags are required: | Flag | Description | | ------------------------------- | ---------------------------------------------------------------------- | | `--metric-name <name>` | The metric to monitor | | `--kind <kind>` | Trigger kind, e.g. `Advanced`, `Performance`, or `HostCPUUsage` | | `--field <field>` | Field to compare: `count`, `counter`, `gauge`, `mean`, `p90`, or `p95` | | `--comparison-operator <op>` | One of `>`, `>=`, `<`, `<=`, `==`, or `!=` | | `--condition-value <number>` | Threshold to compare against | | `--warmup-duration <minutes>` | How long the condition must hold before opening an alert | | `--cooldown-duration <minutes>` | How long it must recover before closing an alert | These flags are optional: | Flag | Description | | ----------------------- | ------------------------------------------------------ | | `--name <text>` | Display name (defaults to the metric name) | | `--description <text>` | Description shown with the trigger | | `--notifier-ids <list>` | Comma-separated notifier IDs to attach | | `--tag <key=value>` | Tag filter (repeat the flag, or comma-separate) | | `--dashboard-id <id>` | Dashboard to link from notifications | | `--no-match-is-zero` | Treat missing datapoints as 0 | | `--format <format>` | Value format, e.g. `duration`, `number`, or `percent` | | `--format-input <unit>` | Input unit for size formats, e.g. `byte` or `kilobyte` | ## Update a trigger Update a trigger by its `--id` (from `triggers list`). An update creates a new version linked to the existing trigger: ```sh Shell theme={null} appsignal-cli triggers update --id <TRIGGER_ID> --app "MyApp" --environment production \ --condition-value 750 ``` `update` accepts the same flags as `create`. ## Archive a trigger Archiving a trigger also closes its associated alerts and incidents: ```sh Shell theme={null} appsignal-cli triggers archive --id <TRIGGER_ID> --app "MyApp" --environment production ``` ## Next steps A trigger opens an incident when it fires. Inspect those with the [incidents](/cli/incidents) commands. # AppSignal Collector Source: https://docs.appsignal.com/collector The AppSignal Collector is a program that works with our [OpenTelemetry integration](/opentelemetry) to collect and process your OpenTelemetry data and send it to AppSignal’s servers. It captures error, performance, and metric data from your application, making it easier to monitor and analyze its behavior. You can install it as a [Linux package](/collector/installation/linux-package) or run it as a container using our [Docker image](/collector/installation/docker-image). ## Features The collector has the following features: * Receive OpenTelemetry tracing data. * Receive OpenTelemetry metrics data. * Collect host metrics from the host it's running on. # AppSignal Collector configuration Source: https://docs.appsignal.com/collector/configuration To start collecting and reporting data, the AppSignal collector must be configured. This documentation explains what options can be configured in the collector and how the configuration is loaded. ## Configuration methods ### Configuration file The AppSignal collector can be configured with a configuration file. This method is required for the [Linux package installation method][linux package]. You need to find or create the configuration file at `/etc/appsignal-collector.conf`. Once you've located or created a configuration file, you can configure the collector using the options listed on the [options page][options]. #### Example configuration file Below is an example of an `appsignal-collector.conf` configuration file. For the complete list of options, please see the [configuration options][options] page. <CodeGroup> ```toml TOML theme={null} # /etc/appsignal-collector.conf push_api_key = "0000-0000-0000-0000" ``` </CodeGroup> ### System environment variable Another way of configuring AppSignal is to use system environment variables on the host the application is running on. This configuration method is used by the [Collector Docker image][docker image]. Ensure these environment variables are configured in the way that's compatible with your Operating System and that the configuration gets loaded before the collector is started. The [configuration options][options] page lists each config option's equivalent system environment variable. You can use these variables to configure the collector, for example, when configuring your app name: <CodeGroup> ```sh Shell theme={null} # Common Bash example export APPSIGNAL_PUSH_API_KEY="0000-0000-0000-0000" ``` </CodeGroup> [linux package]: /collector/installation/linux-package.html [docker image]: /collector/installation/docker-image.html [options]: /collector/configuration/options.html # Collector configuration options Source: https://docs.appsignal.com/collector/configuration/options The collector can be [configured](/collector/configuration) at start-up using environment variables or a configuration file. The following list includes all configuration options with the name of the environment variable and the name of the key in the configuration file. For more information on how to configure the AppSignal Collector with a configuration file or using environment variables, see our [configuration section](/collector/configuration). ## Available options * Required options * [`push_api_key`](#option-push_api_key) * Options * [`cpu_count`](#option-cpu_count) * [`enable_host_metrics`](#option-enable_host_metrics) * [`files_world_accessible`](#option-files_world_accessible) * [`hostname`](#option-hostname) * [`http_port`](#option-http_port) * [`log_level`](#option-log_level) * [`push_api_endpoint`](#option-push_api_endpoint) * [`running_in_container`](#option-running_in_container) * [`working_directory_path`](#option-working_directory_path) ## push\_api\_key <a /> | Field | Value | | ----------------------- | ------------------------------ | | Config file key | `push_api_key` | | System environment key | `APPSIGNAL_PUSH_API_KEY` | | Required | yes | | Type | `String` | | Default value | nil (This is unset by default) | | Available since version | `0.1.0` | ### Description The organization-level authentication key to authenticate with our Push API. Read more about the [AppSignal Push API key](/appsignal/terminology#push-api-key). ## cpu\_count <a /> | Field | Value | | ----------------------- | --------------------- | | Config file key | `cpu_count` | | System environment key | `APPSIGNAL_CPU_COUNT` | | Required | no | | Type | `Float` | | Default value | `undefined` | | Available since version | `0.3.0` | ### Description The available CPU capacity of the host, in number of CPUs. This is used to calculate the CPU usage percentage in the host metrics. If not set, the agent will attempt to automatically detect this from cgroups. The number of CPUs can be a fraction, e.g. `0.5`. ## enable\_host\_metrics <a /> | Field | Value | | ----------------------- | ----------------------------------------------------------------------------------------------------------------------------- | | Config file key | `enable_host_metrics` | | System environment key | `APPSIGNAL_ENABLE_HOST_METRICS` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `false` | | Available since version | `0.3.0` | | | <ul><li>`0.8.0`: Disabled by default.</li><li>`0.3.0`: Disabled by default in the appsignal/collector Docker image.</li></ul> | ### Description Set this option to `false` to disable [host metrics](/metrics/host-metrics) collection. On Heroku and Dokku host metrics are disabled by default. This is done because these systems will report inaccurate metrics from within the containers. Host metrics collection on these systems cannot be enabled. For Heroku, use the [Heroku log drain](/heroku/host-metrics) instead. ## files\_world\_accessible <a /> | Field | Value | | ----------------------- | ---------------------------------- | | Config file key | `files_world_accessible` | | System environment key | `APPSIGNAL_FILES_WORLD_ACCESSIBLE` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `true` | | Available since version | `0.1.0` | ### Description If this is set to `true` the [AppSignal working directory](/appsignal/how-appsignal-operates#working-directory) that is created is accessible for all users (Unix permissions `0666`). This is often necessary because processes for the same app run under a different user. Set to `false` to disable this behaviour (Unix permissions `0644`). ## hostname <a /> | Field | Value | | ----------------------- | -------------------- | | Config file key | `hostname` | | System environment key | `APPSIGNAL_HOSTNAME` | | Required | no | | Type | `String` | | Default value | detected from system | | Available since version | `0.3.0` | ### Description This overrides the server's hostname. Useful for when you're unable to set a custom hostname or when a nondescript id is generated for you on hosting services. ## http\_port <a /> | Field | Value | | ----------------------- | --------------------- | | Config file key | `http_port` | | System environment key | `APPSIGNAL_HTTP_PORT` | | Required | no | | Type | `Integer` | | Default value | `8099` | | Available since version | `0.3.0` | ### Description The port used by the collector's HTTP server to receive OpenTelemetry export requests on. ## log\_level <a /> | Field | Value | | ----------------------- | --------------------- | | Config file key | `log_level` | | System environment key | `APPSIGNAL_LOG_LEVEL` | | Required | no | | Type | `String` | | Default value | `info` | | Available since version | `0.1.0` | ### Description <Note> This option sets the severity level of AppSignal's internal logger and does not affect the [logging feature](/logging). </Note> Set the severity level of AppSignal's internal logger. If it is configured to "info" it will log all error, warning and info messages, but not log the debug messages. Setting it to the levels "debug" or "trace" is usually only needed on request from support. Setting the level to "debug"/"trace" could have a slight impact on the disk usage and IO, especially on high-traffic sites. CPU overhead is minimal with the debug option enabled. Accepted values: * error * warning * info * debug * trace ## push\_api\_endpoint <a /> | Field | Value | | ----------------------- | ----------------------------- | | Config file key | `push_api_endpoint` | | System environment key | `APPSIGNAL_PUSH_API_ENDPOINT` | | Required | no | | Type | `String` | | Default value | `https://push.appsignal.com` | | Available since version | `0.1.0` | ### Description Configure the endpoint to send data to AppSignal. This setting will not have to be changed. ## running\_in\_container <a /> | Field | Value | | ----------------------- | -------------------------------- | | Config file key | `running_in_container` | | System environment key | `APPSIGNAL_RUNNING_IN_CONTAINER` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | detected by collector | | Available since version | `0.3.0` | ### Description AppSignal expects to be running on the same machine between different deploys. Set this key to `true` if the application is running in a container, such as with Docker. Newer versions of the AppSignal integration automatically detect its container environment, so no manual configuration is necessary. If you're having trouble with the automatic detection, please [contact support](mailto:support@appsignal.com). This option is set to `true` automatically on [Heroku](http://heroku.com/). ## working\_directory\_path <a /> | Field | Value | | ----------------------- | --------------------------------------------------------------------------------------------------- | | Config file key | `working_directory_path` | | System environment key | `APPSIGNAL_WORKING_DIRECTORY_PATH` | | Required | no | | Type | `String` | | Default value | detected by collector | | Available since version | `0.1.0` | | | <ul><li>This config option was called `working_dir_path` in versions 0.1.0 through 0.3.x.</li></ul> | ### Description Override the location where the AppSignal Collector can store temporary files. Use this option if the default location is not suitable. See our [how AppSignal operates](/appsignal/how-appsignal-operates) page for more information about the purpose of this working directory. If you are running multiple applications using AppSignal on the same server, use this configuration option to select different working directories for every AppSignal instance, otherwise the two instances could conflict with one another. For more information on this scenario see our [running multiple applications on one host](/guides/application/multiple-applications-on-one-host) documentation. <Note> **Note**: The specified path cannot contain Operating Specific file system abstractions, such as the homedir symbol `~` for \*NIX systems. This will be seen as a malformed path. </Note> # Hosted vs self-hosted collectors Source: https://docs.appsignal.com/collector/hosted-vs-self-hosted When using AppSignal's [OpenTelemetry integration](/opentelemetry), you have two options for deploying the AppSignal Collector: * [Hosted](#hosted-collector) * [Self-hosted](#self-hosted-collector) This page will help you understand the differences between these approaches and choose the best option for your use case. ## Hosted collector The hosted collector is a service provided by AppSignal. It runs on AppSignal's infrastructure and receives OpenTelemetry data directly from your applications. ### Benefits * **Zero maintenance**: AppSignal manages the collector for you, including updates, scaling, and monitoring. * **No infrastructure costs**: The hosted collector is included in your AppSignal subscription at no additional charge. * **No setup required**: Great for serverless applications, Platform-as-a-Service deployments (like Heroku, Render), and applications without the option to run additional services like the collector. ### Limitations * **Data privacy**: Your application data arrives at the hosted collector unfiltered. We will filter the data during processing after it arrives. ## Self-hosted collector The self-hosted collector runs on your own infrastructure, either as a [Linux package](/collector/installation/linux-package) or [Docker container](/collector/installation/docker-image). ### Benefits * **Enhanced privacy**: Your application data never leaves your network until it's processed, sanitized, and sent to AppSignal. * **Compliance**: Some applications are legally required to process sensitive data within their own network before sending it externally. * **Additional metrics**: You want to collect host metrics from hosts where you install the collector's [Linux package]. ### Requirements and considerations * **Infrastructure management**: You're responsible for installing, configuring, updating, and scaling the collector. * **Infrastructure costs**: You'll incur costs for the compute resources needed to run the collector. ## Choosing the right option If you need help deciding which collector to use, we advise the following below. If you need more help choosing, please [reach out to us](mailto:contact@support.com). ### Use the hosted collector when * Your application runs on serverless platforms (AWS Lambda, Vercel, Netlify). * You're using Platform-as-a-Service providers (Heroku, Render, Railway) and can't run the collector as a Linux service or Docker container. * You want minimal operational overhead. * You don't have strict data residency requirements. ### Use the self-hosted collector when: * You have strict data privacy or compliance requirements. * You want complete control over your infrastructure, including when the collector is updated. * You have the infrastructure to run the collector. ## Getting started * **Hosted collector**: Follow the [installation wizard](https://appsignal.com/redirect-to/organization?to=sites/new). A hosted collector will be created for you if none exists yet. * **Self-hosted collector**: Start with the [installation overview](/collector/installation) and choose between the [Linux package] or [Docker image](/collector/installation/docker-image). Both options use the same [configuration](/collector/configuration) and provide the same features for collecting and processing your OpenTelemetry data. [Linux package]: /collector/installation/linux-package.html # AppSignal Collector installation Source: https://docs.appsignal.com/collector/installation To provide a complete picture of your application's infrastructure, you should monitor all servers your application depends on, such as database servers. You can do this by running the AppSignal Collector on those machines. ## Installation methods Choose the installation method that works best for your infrastructure. If you're using Docker (Compose) or Kubernetes, use the Docker image. * [Hosted collector](/collector/hosted-vs-self-hosted): have AppSignal host the collector. * [Linux package](/collector/installation/linux-package): run the collector on the host you want to monitor. * [Docker image](/collector/installation/docker-image): run the collector in a Docker container to connect to other containers. * [Platform as a Service](/collector/installation/platform-as-a-service): run the collector in a Docker container, hosted by your hosting provider. If you have more than one application, or instances of an application, we recommend installing the collector to your infrastructure on its own instance, which all applications can report to. This will improve our reporting as we can piece together instrumentation data across different applications (distributed tracing). It is also more resource intensive to install the collector separately on each host. # Collector Docker image installation Source: https://docs.appsignal.com/collector/installation/docker-image The AppSignal collector is available as a Docker image that can be run as a container in Docker (Compose) and Kubernetes infrastructure. We recommend this installation method if you want multiple (instances of) applications to report to one collector rather than install the collector on each application's host. This guide assumes you have Docker installed or that the application's hosting platform uses it. For information on installing Docker locally, see [Docker's official website](https://www.docker.com/get-started). This guide shows you how to configure the AppSignal collector Docker image for your app, using the Docker environment variables options. ## Docker image Add a container/service to your application's infrastructure using the [appsignal/collector][image] Docker image. In your applications, configure OpenTelemetry to export data to the container using the container's name. On this Docker image, all servers are enabled by default to receive data from apps using OpenTelemetry (port 8099). ## Supported platforms The Docker image supports the following platforms. This list can also be viewed per Docker image tag on [Docker Hub page][image] for this image. * x86 64-bit * ARM 64-bit ## Configuration The collector can be configured with environment variables specified in the Docker run command, Docker compose options or Kubernetes configuration. In the examples below, replace `YOUR_PUSH_API_KEY` with your actual AppSignal Push API key and configure it with your application details. The required Push API key can be found in the ["Push & Deploy" section](https://appsignal.com/redirect-to/app?to=info) for any app in your organization and in the ["Add app" wizard](https://appsignal.com/redirect-to/organization?to=sites/new) for your organization. Only the Push API key is required when configuring the collector. It will authorize requests to our Push API. A complete list of configuration options can be found in the [configuration section](/collector/configuration/options). <CodeGroup> ```bash Docker run theme={null} # Docker run example docker run \ --env APPSIGNAL_PUSH_API_KEY=YOUR_PUSH_API_KEY \ --publish "8099:8099" \ appsignal/collector ``` ```yaml Docker compose theme={null} # docker-compose.yml example version: "3" services: appsignal: # Name of the container used as the hostname on which it can be reached image: appsignal/collector environment: - APPSIGNAL_PUSH_API_KEY=YOUR_PUSH_API_KEY ports: - "8099:8099" # OpenTelemetry ``` </CodeGroup> *** That's it! Once you've completed these steps, you should have the AppSignal collector's Docker image up and running, monitoring the host and, if configured, receiving data from other apps. [image]: https://hub.docker.com/r/appsignal/collector # Collector Linux package installation Source: https://docs.appsignal.com/collector/installation/linux-package This documentation explains how to install the AppSignal collector using a Linux package on the host you want to monitor. Select the Operating System your host uses from the navigation on the right to continue. [Let us know](mailto:support@appsignal.com) if you want to run the collector on a distribution not listed here. ## Debian First, make sure the following packages are installed. All the following commands need root permissions. <CodeGroup> ```bash Shell theme={null} sudo apt update sudo apt install curl gpg -y ``` </CodeGroup> The following releases are supported. * Bookworm for Debian 12 (x86\_64 and arm64) * Bullseye for Debian 11 (x86\_64) Follow the instructions for your Debian version. <Tabs> <Tab title="Bookworm"> Import the GPG signing key by running this command: <CodeGroup> ```sh Shell theme={null} curl -fsSL "https://packages.buildkite.com/appsignal/collector-debian-bookworm/gpgkey" | gpg --dearmor -o /etc/apt/keyrings/appsignal_collector-debian-bookworm-archive-keyring.gpg ``` </CodeGroup> Configure the package source by running this command: <CodeGroup> ```sh Shell theme={null} echo -e "deb [signed-by=/etc/apt/keyrings/appsignal_collector-debian-bookworm-archive-keyring.gpg] https://packages.buildkite.com/appsignal/collector-debian-bookworm/any/ any main\ndeb-src [signed-by=/etc/apt/keyrings/appsignal_collector-debian-bookworm-archive-keyring.gpg] https://packages.buildkite.com/appsignal/collector-debian-bookworm/any/ any main" > /etc/apt/sources.list.d/buildkite-appsignal-collector-debian-bookworm.list ``` </CodeGroup> </Tab> <Tab title="Bullseye"> Import the GPG signing key by running this command: <CodeGroup> ```sh Shell theme={null} curl -fsSL "https://packages.buildkite.com/appsignal/collector-debian-bullseye/gpgkey" | gpg --dearmor -o /etc/apt/keyrings/appsignal_collector-debian-bullseye-archive-keyring.gpg ``` </CodeGroup> Configure the package source by running this command: <CodeGroup> ```sh Shell theme={null} echo -e "deb [signed-by=/etc/apt/keyrings/appsignal_collector-debian-bullseye-archive-keyring.gpg] https://packages.buildkite.com/appsignal/collector-debian-bullseye/any/ any main\ndeb-src [signed-by=/etc/apt/keyrings/appsignal_collector-debian-bullseye-archive-keyring.gpg] https://packages.buildkite.com/appsignal/collector-debian-bullseye/any/ any main" > /etc/apt/sources.list.d/buildkite-appsignal-collector-debian-bullseye.list ``` </CodeGroup> </Tab> </Tabs> Then, update apt to get the newly added packages and install the collector. <CodeGroup> ```bash Shell theme={null} apt-get update apt-get install appsignal-collector ``` </CodeGroup> The collector has now been installed. Next up is [configuring the collector](#configuration) so that AppSignal can receive data. ## Ubuntu First, make sure the following packages are installed. All the following commands need root permissions. <CodeGroup> ```bash Shell theme={null} sudo apt update sudo apt install curl gpg -y ``` </CodeGroup> The following releases are supported. * Noble for Ubuntu 24.04 (x86\_64 and arm64) * Jammy for Ubuntu 22.04 (x86\_64) Follow the instructions for your Ubuntu version. <Tabs> <Tab title="Noble"> Import the GPG signing key by running this command: <CodeGroup> ```sh Shell theme={null} curl -fsSL "https://packages.buildkite.com/appsignal/collector-ubuntu-noble/gpgkey" | gpg --dearmor -o /etc/apt/keyrings/appsignal_collector-ubuntu-noble-archive-keyring.gpg ``` </CodeGroup> Configure the package source by running this command: <CodeGroup> ```sh Shell theme={null} echo -e "deb [signed-by=/etc/apt/keyrings/appsignal_collector-ubuntu-noble-archive-keyring.gpg] https://packages.buildkite.com/appsignal/collector-ubuntu-noble/any/ any main\ndeb-src [signed-by=/etc/apt/keyrings/appsignal_collector-ubuntu-noble-archive-keyring.gpg] https://packages.buildkite.com/appsignal/collector-ubuntu-noble/any/ any main" > /etc/apt/sources.list.d/buildkite-appsignal-collector-ubuntu-noble.list ``` </CodeGroup> </Tab> <Tab title="Jammy"> Import the GPG signing key by running this command: <CodeGroup> ```sh Shell theme={null} curl -fsSL "https://packages.buildkite.com/appsignal/collector-ubuntu-jammy/gpgkey" | gpg --dearmor -o /etc/apt/keyrings/appsignal_collector-ubuntu-jammy-archive-keyring.gpg ``` </CodeGroup> Configure the package source by running this command: <CodeGroup> ```sh Shell theme={null} echo -e "deb [signed-by=/etc/apt/keyrings/appsignal_collector-ubuntu-jammy-archive-keyring.gpg] https://packages.buildkite.com/appsignal/collector-ubuntu-jammy/any/ any main\ndeb-src [signed-by=/etc/apt/keyrings/appsignal_collector-ubuntu-jammy-archive-keyring.gpg] https://packages.buildkite.com/appsignal/collector-ubuntu-jammy/any/ any main" > /etc/apt/sources.list.d/buildkite-appsignal-collector-ubuntu-jammy.list ``` </CodeGroup> </Tab> </Tabs> Then, update apt to get the newly added packages and install the collector. <CodeGroup> ```bash Shell theme={null} apt-get update apt-get install appsignal-collector ``` </CodeGroup> The collector has now been installed. Next up is [configuring the collector](#configuration) so that AppSignal can receive data. ## Red Hat Enterprise Linux/CentOS The following [Red Hat releases](https://access.redhat.com/support/policy/updates/errata/) are supported. * RHEL 9 (x86\_64) The following commands need root permissions. If you get a permission error, you may need to use `sudo`. Configure the package source by running this command: <CodeGroup> ```sh Shell theme={null} sh -c 'echo -e "[collector-rpm-9]\nname=Collector RPM 9 \nbaseurl=https://packages.buildkite.com/appsignal/collector-rpm-9/rpm_any/rpm_any/\$basearch\nenabled=1\nrepo_gpgcheck=1\ngpgcheck=0\ngpgkey=https://packages.buildkite.com/appsignal/collector-rpm-9/gpgkey\npriority=1"' > /etc/yum.repos.d/collector-rpm-9.repo ``` </CodeGroup> Then, install the collector. <CodeGroup> ```bash Shell theme={null} dnf install -y appsignal-collector ``` </CodeGroup> The collector has now been installed. Next up is [configuring the collector](#configuration) so that AppSignal can receive data. ## Configuration The collector configuration can be found at `/etc/appsignal-collector.conf`. For a list of all the available options, see the [configuration options](/collector/configuration/options) page. Update the `/etc/appsignal-collector.conf` configuration file to use your organization's Push API key. The required Push API key can be found in the ["Push & Deploy" section](https://appsignal.com/redirect-to/app?to=info) for any app in your organization and in the ["Add app" wizard](https://appsignal.com/redirect-to/organization?to=sites/new) for your organization. <CodeGroup> ```toml Config file theme={null} # /etc/appsignal-collector.conf push_api_key = "<YOUR PUSH API KEY>" ``` </CodeGroup> For example: <CodeGroup> ```toml Config file theme={null} # /etc/appsignal-collector.conf push_api_key = "0000-0000-0000-0000" ``` </CodeGroup> Only the Push API key is required when configuring the collector. It will authorize your application data with our Push API. Once the configuration file is updated, you need to restart the collector. <CodeGroup> ```sh Shell theme={null} systemctl restart appsignal-collector ``` </CodeGroup> The collector should now be running! ## Debugging Check the log output with the following command to see if any problems have been reported. <CodeGroup> ```sh Shell theme={null} journalctl -u appsignal-collector ``` </CodeGroup> # Collector Platform as a Service Installation Source: https://docs.appsignal.com/collector/installation/platform-as-a-service It's possible to install the AppSignal collector in Platform as a Service environments. The installation steps are similar to the [Docker image installation][docker install]. Please follow the [docker installation guide][docker install] and consult the installation guide for your chosen Platform as a Service on how to configure the container. Here are some guides for different platforms: * [Heroku](https://devcenter.heroku.com/categories/deploying-with-docker) * [Render](https://render.com/docs/deploying-an-image) [docker install]: /collector/installation/docker-image.html # Custom instrumentation Source: https://docs.appsignal.com/custom-instrumentation Where to add manual instrumentation when automatic tracing is not enough. Automatic instrumentation gives AppSignal a strong starting point, but some important work in your application is specific to your product. Custom instrumentation helps you add spans, attributes, metadata, and error context in the places that matter most to you. Pick the guide that matches the SDK you use: * [Ruby](/ruby/instrumentation) * [Elixir](/elixir/instrumentation) * [Node.js](/nodejs/3.x/instrumentation) * [Front-end JavaScript](/front-end/span) * [Python](/python/instrumentation) * [Go](/go/custom-instrumentation) * [Java](/java/custom-instrumentation) * [PHP](/php/instrumentation) * [OpenTelemetry](/opentelemetry/custom-instrumentation) If you are extending OpenTelemetry setup specifically, also see [Add additional OpenTelemetry Instrumentation](/guides/instrumentation/additional-opentelemetry-instrumentation). # AppSignal for Elixir Source: https://docs.appsignal.com/elixir AppSignal supports the [Elixir language][elixir-lang] with an [Elixir package][appsignal-package]. The package supports pure Elixir applications and the Phoenix framework out-of-the-box. Other frameworks and packages might require some [custom instrumentation](/elixir/instrumentation). ## Installation To get started with AppSignal for Elixir, follow our guide to [installing AppSignal](/elixir/installation) in your Elixir application for both pure Elixir and Phoenix installations. ## Configuration It's possible to configure the AppSignal Elixir package using an initializer or using environment variables. Read more about [configuring AppSignal](/elixir/configuration). ## Integrations The AppSignal Elixir package also integrates with popular integrations such as the Phoenix framework. We currently support the following integrations: * [Absinthe](/elixir/integrations/absinthe) * [Phoenix](/elixir/integrations/phoenix) * [Plug](/elixir/integrations/plug) * [Ecto](/elixir/integrations/ecto) * [Erlang](/elixir/integrations/erlang) * [Finch](/elixir/integrations/finch) * [HTTPoison](/elixir/integrations/httpoison) * [Oban](/elixir/integrations/oban) * [Tesla](/elixir/integrations/tesla) ## Instrumentation To make your own integrations with AppSignal or to add custom instrumentation to your application, see the [instrumentation](/elixir/instrumentation) documentation. [elixir-lang]: http://elixir-lang.org/ [appsignal-package]: https://hex.pm/packages/appsignal # AppSignal for Elixir: Command line tools Source: https://docs.appsignal.com/elixir/command-line The [AppSignal for Elixir package][package] ships with several command line tools. These tools make it easier to install AppSignal in an application, send deploy notifications and diagnose any problems with the installation. ## Install A command line tool to install AppSignal in an application. Read more about the [appsignal install][cli-install] command line tool. ## Diagnose A self diagnostic tool for the AppSignal for Elixir package. This tool can be used to debug your AppSignal installation and is one of the first thing our support team asks for when there's an issue. Read more about the [appsignal diagnose][cli-diagnose] command line tool. ## Demo A command to demonstrate and test the AppSignal for Elixir package. Useful for testing the AppSignal installation and configuration. Read more about the [appsignal demo][cli-demo] command line tool. ## Check install A command to test if the AppSignal for Elixir package's extension (NIF) was successfully installed. Read more about the [appsignal check install][cli-check-install] command line tool. [package]: https://github.com/appsignal/appsignal-elixir [cli-install]: /elixir/command-line/install.html [cli-diagnose]: /elixir/command-line/diagnose.html [cli-demo]: /elixir/command-line/demo.html [cli-check-install]: /elixir/command-line/check-install.html # AppSignal for Elixir: Check installation tool Source: https://docs.appsignal.com/elixir/command-line/check-install <VersionRequirements /> The AppSignal for Elixir package ships with a command line tool to check if the package's extension ([a NIF](/elixir/why-nif)) was installed correctly. Our package does not error or fail builds when the extension is not installed correctly. This behavior is *by design*. We would rather have no data reported to AppSignal than have entire applications brought down because our extension could not be installed. We know it's not always easy to check if our package and extension were installed correctly. In some cases, failing a build or deployment when this happens is the best approach. The check install tool can help with this. If you want the build to fail when our extension isn't installed correctly, you can run the check installation task in your CI (Continuous Integration) or deployment process as described below. The command will fail with status code `1` when the extension is not installed correctly. ## Usage In your project's command line, run: <CodeGroup> ```bash Bash theme={null} mix appsignal.check_install ``` </CodeGroup> ### With a release binary In your project's command line, run: <CodeGroup> ```bash Bash theme={null} bin/your_app command appsignal_tasks check_install ``` </CodeGroup> ## Exit codes * Exits with status code `0` if the extension installation was successful. * Exits with status code `1` if the extension installation was unsuccessful. # AppSignal for Elixir: Demonstration tool Source: https://docs.appsignal.com/elixir/command-line/demo The AppSignal for Elixir package ships with a command line tool used to send demonstration samples to AppSignal. Upon running it, it sends an error and performance sample to AppSignal from the user's machine. This command line tool is useful when testing AppSignal on a system and validating the local configuration. It tests if the installation of AppSignal has succeeded and if the AppSignal agent is able to run on the machine's architecture and communicate with the AppSignal servers. The same test is also run during installation using [mix appsignal.install](/elixir/command-line/install). Read more about how to use the demonstration command on the [Debugging][debugging] page. This tool is available since version 0.11.0 of the AppSignal for Elixir package. ## Usage On the command line in your project run: <CodeGroup> ```bash Bash theme={null} mix appsignal.demo ``` </CodeGroup> ### With a specific environment <CodeGroup> ```bash Bash theme={null} MIX_ENV=prod mix appsignal.demo ``` </CodeGroup> ### With a release binary <CodeGroup> ```bash Bash theme={null} bin/your_app command appsignal_tasks demo ``` </CodeGroup> ## Exit codes * Exits with status code `0` if the command has completed successfully. * Exits with status code `1` if the command has completed with an error. [debugging]: /support/debugging.html # AppSignal for Elixir: Diagnose tool Source: https://docs.appsignal.com/elixir/command-line/diagnose The AppSignal for Elixir package ships with a self diagnostic tool. This tool can be used to debug your AppSignal installation and is one of the first thing our support team asks for when there's an issue. This tool has been available since version `0.12.0` of the AppSignal for Elixir package. ## The diagnostic report This command line tool is useful when testing AppSignal on a system and validating the local configuration. It outputs useful information to debug issues and it checks if AppSignal agent is able to run on the machine's architecture and communicate with the AppSignal servers. This diagnostic tool collects and outputs the following: * information about the AppSignal package. * information about the host system, Elixir and Erlang. * if the AppSignal [extension](/appsignal/how-appsignal-operates#extension) and [agent](/appsignal/how-appsignal-operates#agent) can run on the host system. * all configured config options (including default values). * if the configuration is valid and active. * if the Push API key is present and valid (internet connection required). * where configuration option values originate from. * if the required system paths exist, are writable, and which user and group are owners. * small parts of the tail from the available log files. Read more about how to use the diagnose command on the [Debugging][debugging] page. ## Submitting the report Since package version `1.3.0` you will be prompted to send the report to AppSignal. If accepted the report will be send to our servers and you will receive a support token. When you [send this support token to us](mailto:support@appsignal.com) we will review the report and help you debug the issue. We've seen that copy-pasting the report output usually loses formatting and makes it harder to read, which is why it's send to our servers in the JSON format. In package version `1.9.0` the option was added to view the report yourself on AppSignal.com. A link to the report is printed in the diagnose output. This web view will also show any validation problems and warnings our system detected. ## Usage On the command line in your project: <CodeGroup> ```bash Bash theme={null} mix appsignal.diagnose ``` </CodeGroup> ### With an Elixir release binary If your Elixir app is packaged in an Elixir release binary, built with `mix release` you will not be able to call the task using `mix`. Instead use the `eval` command on your release binary to call the AppSignal task `diagnose` like so: <CodeGroup> ```bash Bash theme={null} bin/your_app eval ":appsignal_tasks.diagnose()" ``` </CodeGroup> ### With a release binary If your Elixir app is packaged in a release binary with a tool such as [distillery](https://github.com/bitwalker/distillery) you will not be able to call the task using `mix`. Instead use the `command` command on your release binary to call the AppSignal task `diagnose` like so: <CodeGroup> ```bash Bash theme={null} bin/your_app command appsignal_tasks diagnose ``` </CodeGroup> ## Options | Option | Description | | ------------------------------------------------- | -------------------------------------------------------------------------- | | [Environment option](#environment-option) | Set the environment to use in the command, e.g. `production` or `staging`. | | [`--[no-]send-report`](#report-submission-option) | Automatically send, or do not send the report. | ### Environment option Select a specific environment with the CLI. <CodeGroup> ```bash Bash theme={null} MIX_ENV=prod mix appsignal.diagnose ``` </CodeGroup> The environment option is useful when the default environment is not the one you want to diagnose. The diagnose tool will warn you when no environment is selected. ### Report submission option The options to [submit the report](#submitting-the-report) immediately, or not, were added to the AppSignal package version `1.9.0`. Selecting whether or not to send the report with these options will no longer prompt this question, making it easier to use in non-interactive environments. Submit the report to AppSignal: <CodeGroup> ```bash Bash theme={null} mix appsignal.diagnose --send-report ``` </CodeGroup> Do not submit the report to AppSignal: <CodeGroup> ```bash Bash theme={null} mix appsignal.diagnose --no-send-report ``` </CodeGroup> ## Configuration output format ### Configuration option values format The configuration options are printed to the CLI as their inspected values. This means we print them as Elixir would in a console. * Strings values are printed with double quotes around them, e.g. `"My app name"`. * Booleans values are printed as their raw values: `true` and `false`. * List values are printed as a collection of values surrounded by square brackets, e.g. `["HTTP_ACCEPT", "HTTP_ACCEPT_CHARSET"]`. * Empty Lists are printed as two square brackets: `[]`. * Nil values are printed as `nil`. ### Configuration sources The configuration section also prints where values from config options come from. This may help by identifying sources that override values from other config sources. For more on which configuration sources are available and in which order they're loaded and thus their priority, see the [configuration load order](/elixir/configuration/load-order) page. The configuration options are printed as demonstrated below depending on where the configuration option value comes from and how many sources set this option. ```text Shell theme={null} Configuration # Option with a value loaded only from the default source send_params: true # Option with one source # A different source than the default source name: "My app name" (Loaded from file) # Option with multiple sources # Listed in order of priority (highest priority last) active: true Sources: default: false file: false env: true ``` ## Exit codes * Exits with status code `0` if the command has completed successfully. * Exits with status code `1` if the command has completed with an error. [debugging]: /support/debugging.html # AppSignal for Elixir: Install Source: https://docs.appsignal.com/elixir/command-line/install Command line tool to install AppSignal in an Elixir application. Documentation on usage, options and configuration methods. Command line tool to install AppSignal in an Elixir application. The command line tool is primarily used to help set up the configuration for AppSignal. Please follow the [installation guide](/guides/new-application) when adding a new application to AppSignal. After the configuration/installation is completed the installer perform the [demonstration](/elixir/command-line/demo) command line tool and sends demo data to AppSignal servers to help with the installation wizard. This tool is available since version 0.13.0 of the AppSignal for Elixir package. ## Configuration methods There are two configuration methods the installer provides: using a configuration file or using environment variables. ### 1. Configuration file It's possible to configure AppSignal with the Mix configuration. The AppSignal for Elixir package looks for the configuration loaded by Mix in the. Our installer will write the configuration to `config/appsignal.exs` and add an import to your other configuration file(s). When this option is chosen the given Push API key is written to the configuration file. We do not recommend checking this key into version control (git/svn/mercurial/etc). Instead, use a `APPSIGNAL_PUSH_API_KEY` environment variable or a secrets management tool for your application. See the [configuration documentation](/elixir/configuration) for more information. ### 2. Environment variables It's possible to configure AppSignal using only system environment variables. When this option is selected no configuration is written to the file system. See the [configuration documentation](/elixir/configuration) for more information. ## Usage On the command line in your project run: <CodeGroup> ```bash Bash theme={null} mix appsignal.install <Push API key> # For example mix appsignal.install 1234-1234-1234-1234 ``` </CodeGroup> Where your "Push API key" can be found in the [installation wizard](https://appsignal.com/redirect-to/organization?to=sites/new) for your organization. ## Exit codes * Exits with status code `0` if the command has completed successfully. * Exits with status code `1` if the command has completed with an error. # AppSignal Elixir configuration Source: https://docs.appsignal.com/elixir/configuration Configuration. Important, because without it the AppSignal Elixir package won't know which application it's instrumenting or in which environment. On this topic we'll explain how to configure AppSignal, what can be configured in the Elixir package and what the minimal configuration needed is. ## Minimal required configuration The minimal required configuration needed by AppSignal for Elixir are the following items. If they are not present, AppSignal will not send any data to AppSignal.com. * A valid [Push API Key](/appsignal/terminology#push-api-key) * The application's OTP app name * An application name * An application environment (`dev` / `prod` / `test`) * The application environment to be set to `active: true` <CodeGroup> ```elixir Elixir theme={null} # Example minimal config file # config/config.exs config :appsignal, :config, otp_app: :appsignal_phoenix_example, name: "AppsignalPhoenixExample", push_api_key: "your-push-api-key", env: Mix.env, active: true ``` </CodeGroup> Alternatively, you can configure the agent using system environment variables. AppSignal will automatically become active if the `APPSIGNAL_PUSH_API_KEY` environment variable is set. <CodeGroup> ```elixir Elixir theme={null} export APPSIGNAL_OTP_APP="appsignal_phoenix_example" export APPSIGNAL_PUSH_API_KEY="your-push-api-key" export APPSIGNAL_APP_NAME="AppsignalPhoenixExample" export APPSIGNAL_APP_ENV="prod" ``` </CodeGroup> ## Configuration options Read about all the configuration options on the [options page](/elixir/configuration/options). ## Application environments An application can have multiple environments such as "development"/"dev", "test", "staging" and "production". To separate the errors and performance issues that occur in the "development" environment and those in "production", it's possible to set the environment in which the application is running with the `env` configuration option. A typical environment configuration file would contain the following. <CodeGroup> ```elixir Elixir theme={null} # config/prod.exs config :appsignal, :config, active: true, env: :prod ``` </CodeGroup> The above configuration file example is also what is generated by the AppSignal installer per environment. If you activate AppSignal per environment, using `active: true` in the `config/{env}.exs` file, the `active` option is not required in the main `config/config.exs` file. ### Disable AppSignal for tests If you put your entire AppSignal configuration in the `config/config.exs` instead of `config/prod.exs` (e.g. for having AppSignal enabled during development), make sure to put `active: false` in your test configuration unless you want to submit all your test results. <CodeGroup> ```elixir Elixir theme={null} # config/test.exs config :appsignal, :config, active: false ``` </CodeGroup> ## Example configuration <CodeGroup> ```elixir Elixir theme={null} # config/config.exs config :appsignal, :config, otp_app: :appsignal_phoenix_example, name: "AppsignalPhoenixExample", push_api_key: "your-push-api-key", env: Mix.env, ``` </CodeGroup> <CodeGroup> ```elixir Elixir theme={null} # config/test.exs config :appsignal, :config, active: false ``` </CodeGroup> # AppSignal for Elixir load order Source: https://docs.appsignal.com/elixir/configuration/load-order The AppSignal Elixir can be configured in a couple different ways. Through mix configuration or through environment variables. The configuration is loaded in a four step process. Starting with the package defaults and ending with reading environment variables. The configuration options can be mixed without losing configuration from a different option. Using an initializer, a configuration file and environment variables together will work. ## Load order * 1. [Package defaults - `default`](#1-package-defaults) * 2. [System detected settings - `system`](#2-system-detected-settings) * 3. [Mix app config file - `file`](#3-mix-configuration) * 4. [Environment variables - `env`](#4-environment-variables) * 5. [Overrides - `override`](#5-overrides) ## 1. Package defaults The AppSignal package starts with loading its default configuration, setting paths and enabling certain features. The agent defaults can be found in the [configuration options documentation](/elixir/configuration/options). This source is listed as `default` in the [diagnose](/elixir/command-line/diagnose) output. ## 2. System detected settings The package detects what kind of system it's running on and configures itself accordingly. For example, when it's running on Heroku it sets the configuration option `:running_in_container` to `true` and `:log` to `"stdout"`. This source is listed as `system` in the [diagnose](/elixir/command-line/diagnose) output. ## 3. Mix configuration The AppSignal package is most commonly configured with configuration in the Mix configuration file. <CodeGroup> ```elixir Elixir theme={null} # config/config.exs # or config/prod.exs config :appsignal, :config, otp_app: :appsignal_phoenix_example, name: "AppsignalPhoenixExample", push_api_key: "your-push-api-key", env: Mix.env, active: true ``` </CodeGroup> This step will override all given options from the defaults or system detected configuration. This source is listed as `file` in the [diagnose](/elixir/command-line/diagnose) output. ## 4. Environment variables Our integration will look for its configuration in environment variables. When found these will override all given configuration options from previous steps. <CodeGroup> ```bash Bash theme={null} export APPSIGNAL_APP_NAME="AppsignalPhoenixExample" # start your app here ``` </CodeGroup> This source is listed as `env` in the [diagnose](/elixir/command-line/diagnose) output. ## 5. Overrides When all the configuration is known, our integration will do a final check to find out if the configuration doesn't contradict itself or if some defaults config options are not set. The "override" configuration source will include those last configuration changes made by the integration. When it overrides a config option value, this value is leading. For example, at some point we deprecated the `skip_session_data` option in favor of the `send_session_data` option. When the `skip_session_data` config option was configured by the app, but `send_session_data` was not, the integration would use the value of `skip_session_data` to set the `send_session_data` config option value. # Elixir package configuration options Source: https://docs.appsignal.com/elixir/configuration/options The following list includes all configuration options with the name of the environment variable and the name of the key in the configuration file. For more information on how to configure AppSignal with a configuration file or system environment variables, see our [Configuration](/elixir/configuration) topic. ## Available options * Required options * [`active`](#option-active) * [`env`](#option-env) * [`name`](#option-name) * [`otp_app`](#option-otp_app) * [`push_api_key`](#option-push_api_key) * Options * [`bind_address`](#option-bind_address) * [`ca_file_path`](#option-ca_file_path) * [`cpu_count`](#option-cpu_count) * [`debug`](#option-debug) * [`dns_servers`](#option-dns_servers) * [`ecto_repos`](#option-ecto_repos) * [`enable_error_backend`](#option-enable_error_backend) * [`enable_host_metrics`](#option-enable_host_metrics) * [`enable_minutely_probes`](#option-enable_minutely_probes) * [`enable_nginx_metrics`](#option-enable_nginx_metrics) * [`enable_statsd`](#option-enable_statsd) * [`endpoint`](#option-endpoint) * [`files_world_accessible`](#option-files_world_accessible) * [`filter_parameters`](#option-filter_parameters) * [`filter_session_data`](#option-filter_session_data) * [`host_role`](#option-host_role) * [`hostname`](#option-hostname) * [`http_proxy`](#option-http_proxy) * [`ignore_actions`](#option-ignore_actions) * [`ignore_errors`](#option-ignore_errors) * [`ignore_logs`](#option-ignore_logs) * [`ignore_namespaces`](#option-ignore_namespaces) * [`instrument_absinthe`](#option-instrument_absinthe) * [`instrument_ecto`](#option-instrument_ecto) * [`instrument_finch`](#option-instrument_finch) * [`instrument_oban`](#option-instrument_oban) * [`instrument_tesla`](#option-instrument_tesla) * [`log`](#option-log) * [`log_level`](#option-log_level) * [`log_path`](#option-log_path) * [`nginx_port`](#option-nginx_port) * [`report_oban_errors`](#option-report_oban_errors) * [`request_headers`](#option-request_headers) * [`revision`](#option-revision) * [`running_in_container`](#option-running_in_container) * [`send_environment_metadata`](#option-send_environment_metadata) * [`send_params`](#option-send_params) * [`send_session_data`](#option-send_session_data) * [`skip_session_data`](#option-skip_session_data) * [`statsd_port`](#option-statsd_port) * [`transaction_debug_mode`](#option-transaction_debug_mode) * [`working_dir_path`](#option-working_dir_path) * [`working_directory_path`](#option-working_directory_path) ## active <a /> | Field | Value | | ----------------------- | ---------------------------- | | Config file key | `active` | | System environment key | `APPSIGNAL_ACTIVE` | | Required | yes | | Type | Boolean (`true` / `false`) | | Default value | `false` / detected by system | | Available since version | `0.1.0` | ### Description <Note> **Note**: When the [`APPSIGNAL_PUSH_API_KEY`](#option-push_api_key) environment variable is set, this defaults to `true`. This can be overridden by setting the `APPSIGNAL_ACTIVE` system environment variable to `false`: `APPSIGNAL_ACTIVE=false`. </Note> Configure AppSignal to be active or not for a given environment. Most commonly used in the [file configuration](/elixir/configuration) per environment. ## env <a /> | Field | Value | | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | | Config file key | `env` | | System environment key | `APPSIGNAL_APP_ENV` | | Required | yes | | Type | `Atom` | | Default value | `dev` | | Available since version | `0.1.0` | | | <ul><li>`0.9.2`: The environment variable name for this configuration option was renamed from `APPSIGNAL_ENVIRONMENT` to `APPSIGNAL_APP_ENV`.</li></ul> | ### Description The environment of the app to be reported to AppSignal. This option is set by default by our installer, to `Mix.env`. To override it, change the value in `config/appsignal.exs` (or your config file of choice). ```elixir Elixir theme={null} # config/appsignal.exs # or config/config.exs config :appsignal, :config, env: Mix.env # Installer default # Set your own value config :appsignal, :config, env: :staging ``` To override the config option in the system environment, use the `APPSIGNAL_APP_ENV` environment variable. ```sh Shell theme={null} # The method of setting environment variables may differ on your system export APPSIGNAL_APP_ENV=staging mix run ``` The environment variable option is commonly used on platforms, such as Heroku, where apps run in the `production` environment by default. This setting allows an override to set the environment to `staging`, for example. ```sh Shell theme={null} heroku config:set APPSIGNAL_APP_ENV=staging ``` <Note> **Note**: Changing the [name](#option-name) or environment of an existing app will create a new app on AppSignal.com. </Note> <Note> **Note**: Changing the [name](#option-name) or environment of an existing app will create a new app on AppSignal.com. </Note> ## name <a /> | Field | Value | | ---------------------- | ------------------------------ | | Config file key | `name` | | System environment key | `APPSIGNAL_APP_NAME` | | Required | yes | | Type | `String` | | Default value | nil (This is unset by default) | ### Description Name of your application as it should be displayed on AppSignal.com. <Note> **Note**: Changing the name or [environment](#option-env) of an existing app will create a new app on AppSignal.com. </Note> ## otp\_app <a /> | Field | Value | | ----------------------- | ------------------------------ | | Config file key | `otp_app` | | System environment key | `APPSIGNAL_OTP_APP` | | Required | yes | | Type | `Atom` | | Default value | nil (This is unset by default) | | Available since version | `2.0.0` | ### Description The OTP app name of your application, to be used for automatic configuration of instrumentation for libraries like Ecto. ## push\_api\_key <a /> | Field | Value | | ----------------------- | ------------------------------ | | Config file key | `push_api_key` | | System environment key | `APPSIGNAL_PUSH_API_KEY` | | Required | yes | | Type | `String` | | Default value | nil (This is unset by default) | | Available since version | `0.1.0` | ### Description The organization-level authentication key to authenticate with our Push API. Read more about the [AppSignal Push API key](/appsignal/terminology#push-api-key). <Note> **Note**: When the [`APPSIGNAL_PUSH_API_KEY`](#option-push_api_key) system environment variable is set, the [`active`](#option-active) option will default to `true` instead of `false`. This means AppSignal will be consider active for the loaded environment even if `active` is set to `false` in the config file. For more information see the [`active`](#option-active) option. </Note> ## bind\_address <a /> | Field | Value | | ----------------------- | ------------------------ | | Config file key | `bind_address` | | System environment key | `APPSIGNAL_BIND_ADDRESS` | | Required | no | | Type | `String` | | Default value | `127.0.0.1` | | Available since version | `2.7.7` | ### Description A valid IPv4 address the AppSignal agent uses as a binding for its TCP and UDP servers. Use a specific address if you only want the agent to listen to requests made to that address. Set this option to `0.0.0.0` to allow to receive requests from hosts using any IP address. By default it only listens to requests made on the same host. This option is applied to all the agent servers ([StatsD](#option-enable_statsd), [OpenTelemetry](#option-enable_opentelemetry_http) and [NGINX](#option-enable_nginx_metrics)). ## ca\_file\_path <a /> | Field | Value | | ----------------------- | -------------------------------- | | Config file key | `ca_file_path` | | System environment key | `APPSIGNAL_CA_FILE_PATH` | | Required | no | | Type | `String` | | Default value | Packaged `cacert.pem` file path. | | Available since version | `0.12.0` | ### Description Configure the path of the SSL certificate file. By default this points to the AppSignal [vendored `cacert.pem` file](https://github.com/appsignal/appsignal-elixir/blob/f90759c04a4ff0274e2566704a462d652c988a70/priv/cacert.pem) in the package itself. Use this option to point to another certificate file if there's a problem connecting to our API. <Note> **Note**: The specified path cannot contain Operating Specific file system abstractions, such as the homedir symbol `~` for \*NIX systems. This will be seen as a malformed path. </Note> ## cpu\_count <a /> | Field | Value | | ----------------------- | --------------------- | | Config file key | `cpu_count` | | System environment key | `APPSIGNAL_CPU_COUNT` | | Required | no | | Type | `Float` | | Default value | `undefined` | | Available since version | `2.9.1` | ### Description The available CPU capacity of the host, in number of CPUs. This is used to calculate the CPU usage percentage in the host metrics. If not set, the agent will attempt to automatically detect this from cgroups. The number of CPUs can be a fraction, e.g. `0.5`. ## debug <a /> | Field | Value | | ----------------------- | ---------------------------------------------------------------------------------------------------------------- | | Config file key | `debug` | | System environment key | `APPSIGNAL_DEBUG` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `false` | | Available since version | `1.0.0` | | | <ul><li>Deprecated since version 2.2.8 in favor of the [`log_level` config option](#option-log_level).</li></ul> | ### Description <Warning> **Warning**: This config option is deprecated in Elixir package 2.2.8. Please use the [`log_level`](#option-log_level) option instead for Elixir package 2.2.8 and newer. </Warning> Enable debug logging, this is usually only needed on request from support. With this option enabled AppSignal will log a lot more information about decisions that are made during metrics collection and when data is sent to AppSignal.com servers. Enabling debug logging could have a slight impact on the disk usage and IO, especially on high-traffic sites. CPU overhead is minimal with the debug option enabled. <Note> This option sets the severity level of AppSignal's internal logger. This configuration option does not affect the [logging feature](/logging). </Note> ## dns\_servers <a /> | Field | Value | | ----------------------- | ----------------------- | | Config file key | `dns_servers` | | System environment key | `APPSIGNAL_DNS_SERVERS` | | Required | no | | Type | `list(String)` | | Default value | `[]` | | Available since version | `1.3.0.beta.2` | ### Description Configure DNS servers for the AppSignal agent to use. <CodeGroup> ```elixir Elixir theme={null} # config/config.exs config :appsignal, :config, dns_servers: ["8.8.8.8", "8.8.4.4"] ``` ```sh Shell theme={null} # In the host environment export APPSIGNAL_DNS_SERVERS="8.8.8.8,8.8.4.4" ``` </CodeGroup> If you're affected by our [DNS timeouts](/support/known-issues#dns-timeouts), try setting a DNS server manually using this option that doesn't use more than **4** dots in the server name. * Acceptable values: `8.8.8.8`, `my.custom.local.server`. * Not acceptable values: `foo`, `my.awesome.custom.local.dns.server`. If the DNS server cannot be reached the agent will fall back on the host's DNS configuration and output a message in the `appsignal.log` file: `A problem occurred while setting DNS servers`. ## ecto\_repos <a /> | Field | Value | | ----------------------- | ---------------------- | | Config file key | `ecto_repos` | | System environment key | `APPSIGNAL_ECTO_REPOS` | | Required | no | | Type | `list(String)` | | Default value | `nil` | | Available since version | `2.0.0` | ### Description Configure which Ecto repos to instrument queries for. If unset, AppSignal will automatically find your repos through your application configuration. <CodeGroup> ```elixir Elixir theme={null} # config/config.exs config :appsignal, :config, ecto_repos: [AppsignalPhoenixExample.Repo, AppsignalPhoenixExample.AnotherRepo] ``` ```sh Shell theme={null} # In the host environment export APPSIGNAL_ECTO_REPOS="AppsignalPhoenixExample.Repo,AppsignalPhoenixExample.AnotherRepo" ``` </CodeGroup> ## enable\_error\_backend <a /> | Field | Value | | ----------------------- | -------------------------------- | | Config file key | `enable_error_backend` | | System environment key | `APPSIGNAL_ENABLE_ERROR_BACKEND` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `true` | | Available since version | `2.4.1` | ### Description Enables the error backend in the Elixir integration. ## enable\_host\_metrics <a /> | Field | Value | | ---------------------- | ------------------------------- | | Config file key | `enable_host_metrics` | | System environment key | `APPSIGNAL_ENABLE_HOST_METRICS` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | \`\`true` / detected by system` | ### Description Set this option to `false` to disable [host metrics](/metrics/host-metrics) collection. On Heroku and Dokku host metrics are disabled by default. This is done because these systems will report inaccurate metrics from within the containers. Host metrics collection on these systems cannot be enabled. For Heroku, use the [Heroku log drain](/heroku/host-metrics) instead. ## enable\_minutely\_probes <a /> | Field | Value | | ----------------------- | ---------------------------------- | | Config file key | `enable_minutely_probes` | | System environment key | `APPSIGNAL_ENABLE_MINUTELY_PROBES` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `true` | | Available since version | `1.10.1` | ### Description Enables the [minutely probes](/elixir/instrumentation/minutely-probes) system. ## enable\_nginx\_metrics <a /> | Field | Value | | ----------------------- | -------------------------------- | | Config file key | `enable_nginx_metrics` | | System environment key | `APPSIGNAL_ENABLE_NGINX_METRICS` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `false` | | Available since version | `2.5.2` | ### Description Set to `true` to enable the NGINX metrics server. [See the NGINX metrics documentation for details.](/metrics/nginx) When enabled, the AppSignal agent will listen to a `localhost`-bound server on port 27649. If you're running several AppSignal-instrumented applications in the same server, this configuration option can only be enabled in one of them. ## enable\_statsd <a /> | Field | Value | | ----------------------- | -------------------------- | | Config file key | `enable_statsd` | | System environment key | `APPSIGNAL_ENABLE_STATSD` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `false` | | Available since version | `2.2.6` | ### Description Enables the [StatsD server](/standalone-agent/statsd) in the AppSignal agent. When enabled, the AppSignal agent will listen to a `localhost`-bound server on port 8125. If you're running several AppSignal-instrumented applications in the same server, this configuration option can only be enabled in one of them. ## endpoint <a /> | Field | Value | | ---------------------- | ----------------------------- | | Config file key | `endpoint` | | System environment key | `APPSIGNAL_PUSH_API_ENDPOINT` | | Required | no | | Type | `String` | | Default value | `https://push.appsignal.com` | ### Description Configure the endpoint to send data to AppSignal. This setting will not have to be changed. ## files\_world\_accessible <a /> | Field | Value | | ----------------------- | ---------------------------------- | | Config file key | `files_world_accessible` | | System environment key | `APPSIGNAL_FILES_WORLD_ACCESSIBLE` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `true` | | Available since version | `1.3.4` | ### Description If this is set to `true` the [AppSignal working directory](/appsignal/how-appsignal-operates#working-directory) that is created is accessible for all users (Unix permissions `0666`). This is often necessary because processes for the same app run under a different user. Set to `false` to disable this behaviour (Unix permissions `0644`). ## filter\_parameters <a /> | Field | Value | | ---------------------- | ----------------------------- | | Config file key | `filter_parameters` | | System environment key | `APPSIGNAL_FILTER_PARAMETERS` | | Required | no | | Type | `list(String)` | | Default value | `[]` | ### Description List of parameter keys that should be ignored using AppSignal filtering. Their values will be replaced with `[FILTERED]` when transmitted to AppSignal. You can configure this with a list of keys in the configuration file. ```elixir Elixir theme={null} # config/appsignal.exs config :appsignal, :config, filter_parameters: ["password", "secret"] ``` Read more about [parameter filtering](/application/parameter-filtering). ## filter\_session\_data <a /> | Field | Value | | ----------------------- | ------------------------------------------------------------------------- | | Config file key | `filter_session_data` | | System environment key | `APPSIGNAL_FILTER_SESSION_DATA` | | Required | no | | Type | `list(String)` | | Default value | `[]` | | Available since version | `1.6.0` | | | <ul><li>An upgrade to version `1.6.3` or higher is recommended.</li></ul> | ### Description List of session data keys that should be ignored using AppSignal filtering. Their values will be replaced with `[FILTERED]` when transmitted to AppSignal. You can configure this with a list of keys in the configuration file. ```elixir Elixir theme={null} # config/appsignal.exs config :appsignal, :config, filter_session_data: ["name", "email", "api_token", "token"] ``` Read more about [session data filtering](/application/session-data-filtering). ## host\_role <a /> | Field | Value | | ----------------------- | ------------------------------ | | Config file key | `host_role` | | System environment key | `APPSIGNAL_HOST_ROLE` | | Required | no | | Type | `String` | | Default value | nil (This is unset by default) | | Available since version | `2.7.7` | ### Description Group hosts by role and generate metrics based on this role. One such metric is the `reporting_hosts` counter metric. A good role indicates what the main role of the server is, like "webserver", "processor", "api", "database", "loadbalancer", etc. ## hostname <a /> | Field | Value | | ----------------------- | -------------------- | | Config file key | `hostname` | | System environment key | `APPSIGNAL_HOSTNAME` | | Required | no | | Type | `String` | | Default value | detected from system | | Available since version | `0.12.0` | ### Description This overrides the server's hostname. Useful for when you're unable to set a custom hostname or when a nondescript id is generated for you on hosting services. ## http\_proxy <a /> | Field | Value | | ---------------------- | ------------------------------ | | Config file key | `http_proxy` | | System environment key | `APPSIGNAL_HTTP_PROXY` | | Required | no | | Type | `String` | | Default value | nil (This is unset by default) | ### Description If you require the agent to connect to the Internet via a proxy set the complete proxy URL in this configuration key. ## ignore\_actions <a /> | Field | Value | | ---------------------- | -------------------------- | | Config file key | `ignore_actions` | | System environment key | `APPSIGNAL_IGNORE_ACTIONS` | | Required | no | | Type | `list(String)` | | Default value | `[]` | ### Description With this config option you can specify a list of actions that will be ignored by AppSignal. Everything that happens including exceptions will not be transmitted to AppSignal. This can be useful to ignore health check endpoints or other actions that you don't want to monitor. Read more about [ignoring actions](/guides/filter-data/ignore-actions). ## ignore\_errors <a /> | Field | Value | | ---------------------- | ------------------------- | | Config file key | `ignore_errors` | | System environment key | `APPSIGNAL_IGNORE_ERRORS` | | Required | no | | Type | `list(String)` | | Default value | `[]` | ### Description List of error classes that will be ignored. Any exception raised with this error class will not be transmitted to AppSignal. Read more about [ignoring errors](/guides/filter-data/ignore-errors). ## ignore\_logs <a /> | Field | Value | | ----------------------- | ----------------------- | | Config file key | `ignore_logs` | | System environment key | `APPSIGNAL_IGNORE_LOGS` | | Required | no | | Type | `list(String)` | | Default value | `[]` | | Available since version | `2.10.0` | ### Description List of log messages that will be ignored. Any log message containing any of the elements of the list will not be transmitted to AppSignal. A small subset of regex syntax is supported, read more about it in our [Ignore Logs](/guides/filter-data/ignore-logs) guide. ## ignore\_namespaces <a /> | Field | Value | | ----------------------- | ----------------------------- | | Config file key | `ignore_namespaces` | | System environment key | `APPSIGNAL_IGNORE_NAMESPACES` | | Required | no | | Type | `list(String)` | | Default value | `[]` | | Available since version | `1.3.0` | ### Description List of namespaces that will be ignored. Any error raised or slow request that occurs in this namespace will not be send to AppSignal. Read more about [namespaces](/application/namespaces). ## instrument\_absinthe <a /> | Field | Value | | ----------------------- | ------------------------------- | | Config file key | `instrument_absinthe` | | System environment key | `APPSIGNAL_INSTRUMENT_ABSINTHE` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `true` | | Available since version | `2.7.0` | ### Description Whether to automatically instrument Telemetry events for the [Absinthe package integration](/elixir/integrations/absinthe), can be `true` or `false`. ## instrument\_ecto <a /> | Field | Value | | ----------------------- | --------------------------- | | Config file key | `instrument_ecto` | | System environment key | `APPSIGNAL_INSTRUMENT_ECTO` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `true` | | Available since version | `2.5.1` | ### Description Whether to automatically instrument Telemetry events for the [Ecto package integration](/elixir/integrations/ecto), can be `true` or `false`. ## instrument\_finch <a /> | Field | Value | | ----------------------- | ---------------------------- | | Config file key | `instrument_finch` | | System environment key | `APPSIGNAL_INSTRUMENT_FINCH` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `true` | | Available since version | `2.5.1` | ### Description Whether to automatically instrument Telemetry events for the [Finch package integration](/elixir/integrations/finch), can be `true` or `false`. ## instrument\_oban <a /> | Field | Value | | ----------------------- | --------------------------- | | Config file key | `instrument_oban` | | System environment key | `APPSIGNAL_INSTRUMENT_OBAN` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `true` | | Available since version | `2.5.1` | ### Description Whether to automatically instrument Telemetry events for the [Oban package integration](/elixir/integrations/oban), can be `true` or `false`. ## instrument\_tesla <a /> | Field | Value | | ----------------------- | ---------------------------- | | Config file key | `instrument_tesla` | | System environment key | `APPSIGNAL_INSTRUMENT_TESLA` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `true` | | Available since version | `2.7.3` | ### Description Whether to automatically instrument Telemetry events for the [Tesla package integration](/elixir/integrations/tesla), can be `true` or `false`. ## log <a /> | Field | Value | | ---------------------- | --------------- | | Config file key | `log` | | System environment key | `APPSIGNAL_LOG` | | Required | no | | Type | `Atom` | | Default value | `:file` | ### Description <Note> This option configures what logger that AppSignal's internal logging functionality will use and does not affect the [logging feature](/logging). **Note**: The [AppSignal agent](/appsignal/how-appsignal-operates), which is used by the integration, will always write to the "appsignal.log" file. </Note> Select which logger the AppSignal integration will use. Accepted values are `file` and `stdout`. See also the `log_path` configuration. * `file` (default) * Write all AppSignal logs to the file system. * `stdout` (default on [Heroku](https://heroku.com)) * Print AppSignal logs in the parent process' STDOUT instead of to a file. Useful with hosting solutions such as container systems and Heroku. ## log\_level <a /> | Field | Value | | ----------------------- | --------------------- | | Config file key | `log_level` | | System environment key | `APPSIGNAL_LOG_LEVEL` | | Required | no | | Type | `String` | | Default value | `info` | | Available since version | `2.2.8` | ### Description <Note> This option sets the severity level of AppSignal's internal logger and does not affect the [logging feature](/logging). </Note> Set the severity level of AppSignal's internal logger. If it is configured to "info" it will log all error, warning and info messages, but not log the debug messages. Setting it to the levels "debug" or "trace" is usually only needed on request from support. Setting the level to "debug"/"trace" could have a slight impact on the disk usage and IO, especially on high-traffic sites. CPU overhead is minimal with the debug option enabled. Accepted values: * error * warning * info * debug * trace ## log\_path <a /> | Field | Value | | ----------------------- | ---------------------------------------------------------------------------------------------- | | Config file key | `log_path` | | System environment key | `APPSIGNAL_LOG_PATH` | | Required | no | | Type | `String` | | Default value | `/tmp` | | Available since version | `1.0.0` | | | <ul><li>`1.9.0`: The default log path was changed from `/tmp/appsignal/` to `/tmp/`.</li></ul> | ### Description <Note> This option configures the location of AppSignal's internal logging file and does not affect the [logging feature](/logging). <br /> **Note**: The specified path cannot contain Operating Specific file system abstractions, such as the homedir symbol `~` for \*NIX systems. This will be seen as a malformed path. </Note> Override the location of the path (directory) where the `appsignal.log` file can be written to. ## nginx\_port <a /> | Field | Value | | ----------------------- | ---------------------- | | Config file key | `nginx_port` | | System environment key | `APPSIGNAL_NGINX_PORT` | | Required | no | | Type | `Integer` | | Default value | `27649` | | Available since version | `2.15.8` | ### Description Configure the port on which the NGINX metrics server is exposed. When AppSignal receives NGINX metrics, it listens on a `localhost`-bound server, by default on port 27649. If you're running several AppSignal-instrumented applications in the same server with NGINX metrics enabled, use this option to configure each application to listen on a different port. ## report\_oban\_errors <a /> | Field | Value | | ----------------------- | ------------------------------ | | Config file key | `report_oban_errors` | | System environment key | `APPSIGNAL_REPORT_OBAN_ERRORS` | | Required | no | | Type | `String` | | Default value | `all` | | Available since version | `2.5.1` | ### Description When to report errors received by the [Oban package integration](/elixir/integrations/oban)'s exception event handler while processing a job. Possible values are: * `all`: Report all errors for every execution of jobs, including retries. * `discard`: Report errors when the job is discarded due to the error. Use this option to only report errors when all job retries have been exhausted. * `none`: Report no errors for jobs, including retries. ## request\_headers <a /> | Field | Value | | ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Config file key | `request_headers` | | System environment key | `APPSIGNAL_REQUEST_HEADERS` | | Required | no | | Type | `list(String)` | | Default value | `["accept", "accept-charset", "accept-encoding", "accept-language", "cache-control", "connection", "content-length", "path-info", "range", "request-method", "request-uri", "server-name", "server-port", "server-protocol"]` | | Available since version | `1.6.0` | | | <ul><li>Upgrade to `1.6.3` or higher is recommend.</li></ul> | ### Description The `request_headers` config option contains a list of HTTP request headers which are read and stored by the AppSignal Elixir package. This `request_headers` config option is an *allowlist*, which means that it will only take headers as specified by this config option. If this config option is unset it will use the AppSignal default. Following list is the AppSignal package default. ```elixir Elixir theme={null} # config/appsignal.exs config :appsignal, :config, request_headers: ~w( accept accept-charset accept-encoding accept-language cache-control connection content-length path-info range request-method request-uri server-name server-port server-protocol ) ``` To configure AppSignal to not store any HTTP request headers on AppSignal transactions, configure the option with an empty list. ```elixir Elixir theme={null} # config/appsignal.exs config :appsignal, :config, request_headers: [] ``` ## revision <a /> | Field | Value | | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | Config file key | `revision` | | System environment key | `APP_REVISION` | | Required | no | | Type | `String` | | Default value | nil (This is unset by default) | | Available since version | `1.5.0` | | | <ul><li>`1.10.12`: Auto detection for Heroku deploys with the Dyno Metadata labs feature enabled.</li><li>`2.7.6`: Auto detection for Render deploys.</li><li>`3.4.7`: Auto detection for Kamal deploys.</li></ul> | ### Description Set the app revision to report the currently running version of your app. AppSignal will create a deploy marker when this value changes, and tag all incoming data with the current revision. When your application is deployed using Kamal, or when it is deployed to Render, or when it is deployed to Heroku and the [Heroku Labs: Dyno Metadata](https://devcenter.heroku.com/articles/dyno-metadata) feature is enabled, the AppSignal integration will automatically detect the Git commit of the current deployment and use it as the revision. You can overwrite the automatically detected revisions in Heroku, Render or Kamal by manually setting the `revision` config option to a custom value. Read more about deploy markers in the [deploy markers topic](/application/markers/deploy-markers). ## running\_in\_container <a /> | Field | Value | | ---------------------- | -------------------------------- | | Config file key | `running_in_container` | | System environment key | `APPSIGNAL_RUNNING_IN_CONTAINER` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | detected by agent | ### Description AppSignal expects to be running on the same machine between different deploys. Set this key to `true` if the application is running in a container, such as with Docker. Newer versions of the AppSignal integration automatically detect its container environment, so no manual configuration is necessary. If you're having trouble with the automatic detection, please [contact support](mailto:support@appsignal.com). This option is set to `true` automatically on [Heroku](http://heroku.com/). ## send\_environment\_metadata <a /> | Field | Value | | ----------------------- | ------------------------------------- | | Config file key | `send_environment_metadata` | | System environment key | `APPSIGNAL_SEND_ENVIRONMENT_METADATA` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `true` | | Available since version | `2.2.8` | ### Description Send environment metadata about the app. For more information please read about [environment metadata](/application/environment-metadata). ## send\_params <a /> | Field | Value | | ----------------------- | -------------------------- | | Config file key | `send_params` | | System environment key | `APPSIGNAL_SEND_PARAMS` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `true` | | Available since version | `1.10.0` | ### Description Whether to skip sending request parameters to AppSignal. For more information please read about [send\_params](/application/parameter-filtering) in filtering request parameters. ## send\_session\_data <a /> | Field | Value | | ----------------------- | ----------------------------- | | Config file key | `send_session_data` | | System environment key | `APPSIGNAL_SEND_SESSION_DATA` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `true` | | Available since version | `2.2.10` | ### Description Set this option to `false` to not send any session data with exception traces and performance issue samples. For more information please read about [request session data filtering](/application/session-data-filtering). ## skip\_session\_data <a /> | Field | Value | | ---------------------- | ----------------------------- | | Config file key | `skip_session_data` | | System environment key | `APPSIGNAL_SKIP_SESSION_DATA` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `false` | ### Description <Warning> **Warning**: This config option is deprecated in the Elixir package 2.2.10. Please use the [`send_session_data`](#option-send_session_data) option instead for newer versions of the Elixir package. </Warning> ## statsd\_port <a /> | Field | Value | | ----------------------- | ----------------------- | | Config file key | `statsd_port` | | System environment key | `APPSIGNAL_STATSD_PORT` | | Required | no | | Type | `Integer` | | Default value | `8125` | | Available since version | `2.7.2` | ### Description Set this option to configure the StatsD HTTP server port of the AppSignal agent process. Configure this port if another process is already running on the machine that is also using this port to avoid conflicts. ## transaction\_debug\_mode <a /> | Field | Value | | ----------------------- | ---------------------------------------------------------------------------------------------------------------- | | Config file key | `transaction_debug_mode` | | System environment key | `APPSIGNAL_TRANSACTION_DEBUG_MODE` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `false` | | Available since version | `1.11.4` | | | <ul><li>Deprecated since version 2.2.9 in favor of the [`log_level` config option](#option-log_level).</li></ul> | ### Description <Warning> **Warning**: This config option is deprecated in Elixir package 2.2.9. Please use the [`log_level`](#option-log_level) option instead for Elixir package 2.2.9 and newer. </Warning> Enable transaction debug mode. This enables very detailed logging of transactions and events which is useful when developing integrations or when events aren not tracked as expected. The log is only written if the general `debug` option is on as well. <Note> This option sets the severity level of AppSignal's internal logger and does not affect the [logging feature](/logging). </Note> ## working\_dir\_path <a /> | Field | Value | | ----------------------- | ---------------------------- | | Config file key | `working_dir_path` | | System environment key | `APPSIGNAL_WORKING_DIR_PATH` | | Required | no | | Type | `String` | | Default value | detected by agent | | Available since version | `1.8.0` | ### Description <Warning> **Warning**: This config option is deprecated in Elixir package 1.8.0. Please use the [`working_directory_path`](#option-working_directory_path) option instead for Elixir package 1.8.0 and newer. </Warning> Override the location where AppSignal for Elixir can store temporary files. Use this option if the default location is not suitable. See our [how AppSignal operates](/appsignal/how-appsignal-operates) page for more information about the purpose of this working directory. If you are running multiple applications using AppSignal on the same server, use this configuration option to select different working directories for every AppSignal instance, otherwise the two instances could conflict with one another. For more information on this scenario see our [running multiple applications on one host](/guides/application/multiple-applications-on-one-host) documentation. ```elixir Elixir theme={null} # config/config.exs config :appsignal, :config, working_dir_path: "/tmp/project_1/" ``` <Note> **Note**: The specified path cannot contain Operating Specific file system abstractions, such as the homedir symbol `~` for \*NIX systems. This will be seen as a malformed path. </Note> ## working\_directory\_path <a /> | Field | Value | | ----------------------- | ----------------------------------------------------------------------------------------------------------- | | Config file key | `working_directory_path` | | System environment key | `APPSIGNAL_WORKING_DIRECTORY_PATH` | | Required | no | | Type | `String` | | Default value | detected by agent | | Available since version | `1.8.0` | | | <ul><li>Please use the [`working_dir_path`](#option-working_dir_path) option on earlier versions.</li></ul> | ### Description Override the location where AppSignal for Elixir can store temporary files. Use this option if the default location is not suitable. See our [how AppSignal operates](/appsignal/how-appsignal-operates) page for more information about the purpose of this working directory. If you are running multiple applications using AppSignal on the same server, use this configuration option to select different working directories for every AppSignal instance, otherwise the two instances could conflict with one another. For more information on this scenario see our [running multiple applications on one host](/guides/application/multiple-applications-on-one-host) documentation. ```elixir Elixir theme={null} # config/appsignal.exs config :appsignal, :config, working_directory_path: "/tmp/project_1/" ``` <Note> **Note**: The specified path cannot contain Operating Specific file system abstractions, such as the homedir symbol `~` for \*NIX systems. This will be seen as a malformed path. </Note> # Installing AppSignal for Elixir Source: https://docs.appsignal.com/elixir/installation Please follow the [installation guide](/guides/new-application) first, when adding a new application to AppSignal. ## Requirements Before you can compile the AppSignal package, make sure the build/compilation tools are installed for your system. Please check the [Supported Operating Systems](/support/operating-systems) page for any system dependencies that may be required. ## Installation Installing the AppSignal package in your Elixir application requires a couple of manual steps. Currently, AppSignal support Phoenix, Plug and pure Elixir apps. If AppSignal does not support your use-case or if you find a problem with the documentation, don't hesitate to [contact us][support]. You can also create a pull-request on our public [Elixir repository][elixir-repo]. ### Installing the package <Note> πŸ“– **Note**: If you're running an umbrella application, see also our [umbrella installation guide](/elixir/installation/umbrella). </Note> <Tip> **Note**: If you use the [Phoenix framework][phoenix] or [Plug][plug], continue with the [integrating AppSignal into Phoenix](/elixir/integrations/phoenix) or [integrating AppSignal into Plug](/elixir/integrations/plug) guides. </Tip> 1. Start by adding `appsignal` to your list of dependencies in `mix.exs`. <CodeGroup> ```elixir Elixir theme={null} # mix.exs def deps do [ {:appsignal, "~> 2.8"} ] end ``` </CodeGroup> 2. Then run `mix deps.get`. 3. Then run `mix appsignal.install YOUR_PUSH_API_KEY` or follow the [manual configuration guide](#configuration). After the installation is complete, start your application. When the AppSignal OTP application starts, it looks for a valid configuration (e.g. an AppSignal Push API key), and start the AppSignal agent. If it can't find a valid configuration, a warning will be logged. See the [Configuration](#configuration) section on how to fully configure the AppSignal agent. ### Configuration Before the AppSignal package works you need to configure it. To be able to send data to AppSignal you first need to [create an account on AppSignal.com](https://appsignal.com/users/sign_up). Or, if you already have an account, click on the "add app" button on [AppSignal.com/accounts](https://appsignal.com/accounts). During the installation process you can run the `mix appsignal.install` command with the hexadecimal [Push API key](/appsignal/terminology#push-api-key) or manually configure AppSignal using the guide below. For more information about configuring the AppSignal package for Elixir, please read our [configuration documentation](/elixir/configuration). #### Manual configuration If you want to manually configure AppSignal you will need to place the AppSignal Push API key you receive in the installation process in your application's `config/config.exs` configuration file. Using the AppSignal configuration you are also able to configure an application name and environment and more. <CodeGroup> ```elixir Elixir theme={null} # config/config.exs config :appsignal, :config, otp_app: :appsignal_phoenix_example, name: "AppsignalPhoenixExample", push_api_key: "your-push-api-key", env: Mix.env, active: true ``` </CodeGroup> Alternatively, you can configure AppSignal using OS environment variables. <CodeGroup> ```sh Shell theme={null} export APPSIGNAL_OTP_APP="appsignal_phoenix_example" export APPSIGNAL_PUSH_API_KEY="your-push-api-key" export APPSIGNAL_APP_NAME="AppsignalPhoenixExample" export APPSIGNAL_APP_ENV="prod" ``` </CodeGroup> For more information about configuring the AppSignal package for Elixir, please read our [configuration options page](/elixir/configuration). ### Run your application! Once you've completed this guide your application is ready to be monitored by AppSignal! Start your application up and perform some requests on it. By triggering an error or two you'll also test the error reporting. [Contact us][support] if you have questions regarding installation or encountered any problems during the installation. ### Optional: Add Phoenix instrumentation Read more about how you can integrate more instrumentation in your Phoenix application in our [integrating Phoenix guide](/elixir/integrations/phoenix). ### Optional: Add Plug instrumentation Read more about how you can integrate more instrumentation in your Plug application in our [integrating Plug guide](/elixir/integrations/plug). ### Optional: Add custom instrumentation Add custom instrumentation to your application to get a more in-depth view of what's happening in your application. Read more about custom instrumentation in our [instrumentation documentation](/elixir/instrumentation). *** <Note> πŸ“– Continue with our [installation guide](/guides/new-application). </Note> ## Uninstall Uninstall AppSignal from your app by following the steps below. When these steps are completed your app will no longer send data to the AppSignal servers. 1. In the `mix.exs` of your app, delete the `{:appsignal, "~> 2.0"}` line. 2. Run `mix deps.get` to update your `mix.lock` with the removed packages state. 3. Remove any AppSignal [configuration files](/elixir/configuration/) from your app. * Configuration file location: `config/appsignal.exs` * And its references in any other files in `config/*.exs` 4. Remove any system environment variables from your development, staging, production, etc. hosts. * Environment variables prefixed with `APPSIGNAL_` * Environment variable [`APP_REVISION`](/elixir/configuration/options#option-revision) 5. Commit, deploy and restart your app. * This will make sure the AppSignal servers won't continue to receive data from your app. 6. Optional: Make sure no `appsignal-agent` processes are running in the background. * Check the output of `ps aux | grep appsignal-agent` and kill the processes still running. 7. Finally, [remove the app](/guides/application/deleting-applications) on AppSignal.com. <Note> πŸ“– Continue with our [uninstall guide](/guides/application/deleting-applications). </Note> [support]: mailto:support@appsignal.com [elixir-repo]: https://github.com/appsignal/appsignal-elixir [phoenix]: http://www.phoenixframework.org/ [plug]: https://github.com/elixir-plug/plug # Installing AppSignal in an umbrella application Source: https://docs.appsignal.com/elixir/installation/umbrella AppSignal works with umbrella applications, but there are some things to keep in mind. The dependency should be added to each nested application inside the umbrella, and the configuration should be added to the umbrella's main configuration file. This guide goes over the first steps to install AppSignal in your umbrella Elixir and Phoenix projects. For more information and further steps, check out the [main installation guide](/elixir/installation). ## Installation Add the AppSignal dependency to each application that will use it. This includes all Phoenix applications and all backend applications that communicate with the database. <CodeGroup> ```elixir Elixir theme={null} defp deps do [ {:appsignal, "~> 2.0"} ] end ``` </CodeGroup> Then, run AppSignal’s installer in the umbrella’s root directory to add the configuration to the umbrella application’s configuration files. <CodeGroup> ```sh Shell theme={null} $ mix appsignal.install YOUR_PUSH_API_KEY ``` </CodeGroup> By default, each nested application in an umbrella uses the main umbrella configuration, so the nested apps should all have access to the main configuration. ## Phoenix The installation for Phoenix in an umbrella application are mostly the same as [setting up AppSignal β€œregular” Phoenix application](/elixir/integrations/phoenix). One thing to keep in mind is to `use Appsignal.Phoenix` in your application’s endpoint file. If you have multiple nested Phoenix applications, use the module in each. <Tip> If you include `use Plug.Builder` or any other module that redefines the `call/2` function, make sure to place the `use Appsignal.Phoenix` line after that. </Tip> <CodeGroup> ```elixir Elixir theme={null} defmodule AppsignalPhoenixExampleWeb.Endpoint do use Phoenix.Endpoint, otp_app: :appsignal_phoenix_example use Appsignal.Phoenix # ... end ``` </CodeGroup> # Custom instrumentation for Elixir Source: https://docs.appsignal.com/elixir/instrumentation AppSignal provides many ways to bring more insights in your application by adding more instrumentation or tagging the data that appears in the UI at AppSignal.com. * [Integrating AppSignal](/elixir/instrumentation/integrating-appsignal) * [Instrumentation](/elixir/instrumentation/instrumentation) * [Exception handling](/elixir/instrumentation/exception-handling) * [Minutely probes](/elixir/instrumentation/minutely-probes) * [Mix tasks](/elixir/instrumentation/mix_tasks) * [Command line tool](/elixir/command-line) ## Contact us Don't hesitate to [contact us](mailto:support@appsignal.com) if you run into any issues while implementing custom instrumentation. We're here to help. # Exception handling Source: https://docs.appsignal.com/elixir/instrumentation/exception-handling In most applications some errors will get raised that aren't related to possible bugs in your code, they just happen when your app gets into contact with the real world. Bots might drop by and try to automatically post forms, outdated links might direct visitors to content that doesn't exist anymore and so on. To avoid these errors from being raised as problems in AppSignal it's possible to add exception handling to your code or even let AppSignal completely ignore certain errors. ## Ignore errors The AppSignal configuration makes it possible to [ignore errors](/guides/filter-data/ignore-errors). By providing a list of specific errors AppSignal will not send alerts when these errors are raised. ## Appsignal.set\_error/3 If you want to rescue exceptions in your application to prevent crashes, but still want to track the occurrence you can use [`Appsignal.set_error/2`][hexdocs-set_error-2] to add the exception to the current AppSignal transaction: <CodeGroup> ```elixir Elixir theme={null} try do raise "Exception!" rescue exception -> Appsignal.set_error(exception, __STACKTRACE__) end ``` </CodeGroup> ### Erlang The AppSignal integration tries its best to convert errors raised from Erlang to Elixir exceptions. For example, a `:badarg` raised from Erlang is automatically converted to an `ArgumentError`. However, sometimes the best it can do is wrapping the error originating from Erlang in an `ErlangError`. Since these don’t give much insight into the underlying issue, we recommend adding information from within your application by catching the error, creating an Elixir exception yourself and adding that to the current span using the `set_error/2` function. <Warning> **NOTE:** `Appsignal.set_error/2` was added in AppSignal for Elixir 2.1.0. If you're on a lower version, use `Appsignal.set_error/3` instead. </Warning> On versions before 2.1.0, use `catch` and `Appsignal.send_error/3`: <CodeGroup> ```elixir Elixir theme={null} try do raise "Exception!" catch kind, reason -> Appsignal.set_error(kind, reason, __STACKTRACE__) end ``` </CodeGroup> The exception will be tracked by AppSignal like any other error, and it allows you to provide custom error handling and fallbacks. If you do not have an error object when calling `send_error`, but still want to report the scenario as an error, it's also possible to initialize a custom error struct. <CodeGroup> ```elixir Elixir theme={null} defmodule MyCustomError do defexception message: "default message" # Customize if you call it without a custom message end case Worker.do_something() do :ok -> IO.puts "yay!" {:error, message} -> Appsignal.set_error(:error, %MyCustomError{ message: message }, []) end ``` </CodeGroup> **Note:** This function only works when there is an AppSignal transaction active. Otherwise the error will be ignored. Please see [`Appsignal.send_error/3`](#appsignalsend_error3) for sending errors without an AppSignal transaction. ## Appsignal.send\_error/3 AppSignal provides a mechanism to track errors that occur in code that's not in a web or background job context, such as Mix tasks. This is useful for instrumentation that doesn't automatically create AppSignal transactions to profile. You can use the [`Appsignal.send_error/3`][hexdocs-send_error] function to directly send an exception to AppSignal from any place in your code without starting an AppSignal transaction first. <CodeGroup> ```elixir Elixir theme={null} try do raise "Exception!" catch kind, reason -> Appsignal.send_error(kind, reason, __STACKTRACE__) end ``` </CodeGroup> If you do not have an error object when calling `send_error`, but still want to report the scenario as an error, it's also possible to initialize a custom error struct. <CodeGroup> ```elixir Elixir theme={null} defmodule MyCustomError do defexception message: "default message" # Customize if you call it without a custom message end case Worker.do_something() do :ok -> IO.puts "yay!" {:error, message} -> Appsignal.send_error(:error, %MyCustomError{ message: message }, []) end ``` </CodeGroup> ### Additional metadata To add metadata to the sent error, pass a function as the fourth argument to `Appsignal.send_errror/4`: <CodeGroup> ```elixir Elixir theme={null} try do raise "Exception!" catch kind, reason -> Appsignal.send_error(kind, reason, __STACKTRACE__, fn span -> Appsignal.Span.set_attribute(span, "key", "value") end) end ``` </CodeGroup> <Warning> **NOTE:** `Appsignal.send_error/4` was added in AppSignal for Elixir 2.1.0. </Warning> [hexdocs-set_error-2]: https://hexdocs.pm/appsignal/Appsignal.Instrumentation.html#set_error/2 [hexdocs-send_error]: https://hexdocs.pm/appsignal/Appsignal.Instrumentation.html#send_error/3 # Custom instrumentation for Elixir Source: https://docs.appsignal.com/elixir/instrumentation/instrumentation In order to find out what specific pieces of code are causing performance problems it's useful to add custom instrumentation to your application. This allows us to create better breakdowns of which code runs slowest and what type of action the most amount of time was spent on. Custom instrumentation is possible in two ways: using function decorators and instrumentation helper functions. The function decorators are easiest to use, but are less flexible than the instrumentation helper functions. This short guide will help you set up custom instrumentation. More details on the usage of certain helpers can be found in the Hex docs for the [AppSignal package](https://hexdocs.pm/appsignal/). <Tip> **Note**: Make sure you've [integrated AppSignal](/elixir/instrumentation/integrating-appsignal) before adding custom instrumentation to your application if it's not automatically integrated by one of our supported [integrations](/elixir/integrations). </Tip> <Tip> **Note**: This page only describes how to add performance instrumentation to your code. To track errors please read our [exception handling](/elixir/instrumentation/exception-handling) guide. </Tip> ## `Appsignal.instrument/2-3` The `instrument/2` function is used to add instrumentation by wrapping a piece of code in a span. A span eventually becomes a sample, or an event in another span's sample in AppSignal. ### Add spans to traces In the following example we have a Phoenix controller with an `index/2` function which calls a slow function. The `slow` function is instrumented using the `Appsignal.instrument/2` function which records it as a separate event in this Phoenix request. It will show up on AppSignal.com in the event timeline of this sample to provide more insight in where the most time was spent during the request. <CodeGroup> ```elixir Elixir theme={null} defmodule AppsignalPhoenixExampleWeb.PageController do use AppsignalPhoenixExampleWeb, :controller def index(conn, _params) do slow() render(conn, "index.html") end defp slow do Appsignal.instrument("slow", fn -> :timer.sleep(1000) end) end end ``` </CodeGroup> Here, we wrap our function's contents with a call to `Appsignal.instrument3`, and we pass `"slow"` as the name for the event. ### Starting new traces In the Phoenix example an AppSignal trace has already been started, thanks to the first-party support for Phoenix in the AppSignal package. Not all frameworks and packages are currently supported directly and automatically start traces. The same is true for your own pure Elixir applications. Like when adding spans to already-instrumented traces, a new root span is created using the `Appsignal.instrument/2` function: <CodeGroup> ```elixir Elixir theme={null} defmodule AppsignalElixirExample do def example_fn do Appsignal.instrument("instrument", fn -> :timer.sleep(500) end) end end ``` </CodeGroup> This example creates a sample named "instrument" in the "background" namespace in AppSignal. The name will also be used as the category name for the main span. To use a different category name, use `instrument/3` instead: <CodeGroup> ```elixir Elixir theme={null} defmodule AppsignalElixirExample do def example_fn do Appsignal.instrument("instrument", "call.instrument", fn -> :timer.sleep(500) end) end end ``` </CodeGroup> When passing a function that takes an argument, the `instrument/2-3` function calls it with the opened span to allow further customization. See the docs on hex.pm for [all available Span functions](https://hexdocs.pm/appsignal/Appsignal.Span.html). <CodeGroup> ```elixir Elixir theme={null} defmodule AppsignalElixirExample do def example_fn do Appsignal.instrument("Build complicated SQL query", "prepare_query.sql", fn span -> # Example of building a complex SQL query in the instrument block and performing it query = "SOME complicate SQL query" # The body is only set here because it's the value being calculated and instrumented in this function Appsignal.Span.set_sql(span, query) Database.perform_query(query) end) end end ``` </CodeGroup> ### Exception handling To report errors using custom instrumentation please read more in our [exception handling guide](/elixir/instrumentation/exception-handling). ## Function decorators Using the `Appsignal.Instrumentation.Decorators` decorator module, it's possible add custom instrumentation to your Elixir applications without changing the functions' contents. ### Transaction events In the following example we have a Phoenix controller with an `index/2` function which calls a slow function. The `slow` function is instrumented using the AppSignal `transaction_event` decorator which records it as a separate event in this Phoenix request. It will show up on AppSignal.com in the event timeline of this transaction sample to provide more insight in where the most time was spent during the request. <CodeGroup> ```elixir Elixir theme={null} # Phoenix controller example defmodule PhoenixExample.PageController do use PhoenixExample.Web, :controller # Include this use Appsignal.Instrumentation.Decorators def index(conn, _params) do slow() render conn, "index.html" end # Decorate this function to add custom instrumentation @decorate transaction_event() defp slow do :timer.sleep(1000) end end ``` </CodeGroup> If you want to group certain events together under the same event group (other group are `phoenix_controller`, `phoenix_render`, `ecto`, etc.) you can also supply a group name to the `transaction_event` decorator. <CodeGroup> ```elixir Elixir theme={null} @decorate transaction_event("github_api") defp get_data_from_github do # Third-party API call end ``` </CodeGroup> This will create an event `get_data_from_github.github_api` in the event timeline. For more information on how event names are used, please read our [event naming guidelines](/api/event-names). ### Transactions In the Phoenix example an AppSignal transaction has already been started, thanks to the first-party support for Phoenix in the AppSignal package. Not all frameworks and packages are currently supported directly and automatically start transactions. The same is true for your own pure Elixir applications. In order to track `transaction_event` decorators we will need to start an AppSignal transaction beforehand. We can start a transaction with the `transaction` function decorator. <CodeGroup> ```elixir Elixir theme={null} # Pure Elixir example defmodule FunctionDecoratorsExample do # Include this use Appsignal.Instrumentation.Decorators # No transaction is started beforehand like in Phoenix, so we need to start # it ourselves. @decorate transaction() def call do slow() # ... end # Decorate this function to add custom instrumentation @decorate transaction_event() defp slow do :timer.sleep(1000) end end ``` </CodeGroup> **Note**: When using pure Elixir applications, make sure that the AppSignal application is started before you start a transaction. For more information, see how to [integrate AppSignal](/elixir/instrumentation/integrating-appsignal). ### Namespaces In order to differentiate between HTTP requests and background jobs we can pass a namespace to the transaction once we start it. The following two namespaces are official namespaces supported by AppSignal. * `http_request` - the default - is called the "web" namespace * `background_job` - creates the "background" namespace <CodeGroup> ```elixir Elixir theme={null} defmodule FunctionDecoratorsExample do # Include this use Appsignal.Instrumentation.Decorators # No namespace argument defaults to `:http_request` @decorate transaction() def web_function do # do stuff end # The "background" namespace @decorate transaction(:background_job) def background_function do # do stuff end end ``` </CodeGroup> For more information about what namespaces are, please see our [namespaces](/application/namespaces) documentation. ### Custom namespaces You can also create your own namespaces to track transactions in a separate part of your application such as an administration panel. This will group all the transactions with this namespace in a separate section on AppSignal.com so that slow admin controllers don't interfere with the averages of your application's speed. <CodeGroup> ```elixir Elixir theme={null} @decorate transaction(:admin) def some_function do # do stuff end ``` </CodeGroup> ### Phoenix channels There is a custom function decorator for Phoenix channels. This decorator is meant to be put before the `handle_in/3` function of a `Phoenix.Channel` module. <CodeGroup> ```elixir Elixir theme={null} defmodule FunctionDecoratorsExample.MyChannel do # Include this use Appsignal.Instrumentation.Decorators # Add this channel function decorator @decorate channel_action() def handle_in("ping", _payload, socket) do # your code here.. end end ``` </CodeGroup> Channel events will be displayed under the "background" namespace, showing the channel module and the action argument that it's used on. ## Manually creating and closing spans In some cases it can be useful to manually handle spans. You can use the span API to instrument tasks for example: <CodeGroup> ```elixir Elixir theme={null} def index(conn, _params) do current = Appsignal.Tracer.current_span() fn -> span = "http_request" |> Appsignal.Tracer.create_span(current) |> Appsignal.Span.set_name("name") |> Appsignal.Span.set_attribute("appsignal:category", "category") :timer.sleep(1000) Appsignal.Tracer.close_span(span) end |> Task.async() |> Task.await() render(conn, "index.html") end ``` </CodeGroup> # Integrating AppSignal in Elixir Source: https://docs.appsignal.com/elixir/instrumentation/integrating-appsignal It's possible that AppSignal does not provide automatic integration for your framework of choice, or maybe you're using your own application setup. When AppSignal does not support something out-of-the-box it's still possible to instrument applications. AppSignal needs to be configured and started once at the beginning of a process. It can be [configured](/elixir/configuration) through Mix configuration or by using environment variables. ## Configuration The AppSignal for Elixir package needs to be configured before it can send data to AppSignal.com. There are two methods of configuration. Using the mix configuration and using environment variables. See the [configuration pages](/elixir/configuration) for the full configuration guide. ## Starting AppSignal In order for AppSignal to instrument your application the AppSignal process must be started in the Erlang BEAM VM. Make sure to put this line in a location that is always run in your application. <CodeGroup> ```elixir Elixir theme={null} {:ok, _} = Application.ensure_all_started(:appsignal) ``` </CodeGroup> **Note**: This is not required for frameworks that AppSignal integrates with, such as Phoenix, but it is for pure Elixir applications and code outside these integrations, such as independent tasks or background jobs. ## Add custom instrumentation Continue with our guide to [add custom instrumentation](/elixir/instrumentation/instrumentation) to your application. # Minutely probes Source: https://docs.appsignal.com/elixir/instrumentation/minutely-probes Minutely probes are a mechanism to periodically send [custom metrics](/metrics/custom) to AppSignal. This is a system that is included in the AppSignal Elixir package by default. At the start of every minute the minutely probes are triggered to collect metrics and then snoozed until the next minute. By default the AppSignal Elixir package enables a probe for the ErlangVM. <Tip> **Note**: We recommend using AppSignal Elixir package `1.10.1` and up when using this feature. </Tip> ## Usage The minutely probes allow the AppSignal Elixir package to collect [custom metrics](/metrics/custom) by default for the ErlangVM and app-specific metrics by [creating your own probe](#creating-probes). ### Multiple instances Once activated, the minutely probes system runs on every instance of an app. This means that if a probe report metrics without some kind of differentiating tag, global metrics may be overwritten by instance-level metrics. To remedy this, we suggest [tagging](/metrics/custom#metric-tags) your metrics with the hostname or something else unique for each instance. For example, the ErlangVM Probe tags metrics with the hostname by default. Alternatively you can [disable minutely probes](/elixir/configuration/options#option-enable_minutely_probes) for all but one instance, on which the minutely probes process is run. We suggest using the [`APPSIGNAL_ENABLE_MINUTELY_PROBES`](/elixir/configuration/options#option-enable_minutely_probes) environment variable to only enable it on the instance of your choosing. ## Configuration The minutely probes are configured using the [`enable_minutely_probes`](/elixir/configuration/options#option-enable_minutely_probes) config option. The default value is `true`. ## Creating probes If you want to track more [custom metrics](/metrics/custom) from your app than our default probes do, you can add your own probe(s). An AppSignal minutely probe can be an [Anonymous function](#anonymous-function), or a [Module based function](#module-based-function). ### Anonymous function The simplest probe type to register. If you have no dependencies for your probe this is the preferred method. <CodeGroup> ```elixir Elixir theme={null} Appsignal.Probes.register(:my_probe, fn -> Appsignal.set_gauge("database_size", 10) end) ``` </CodeGroup> ### Module based function A module based function can be useful if you have a more complex probe, or a probe that has dependencies. <CodeGroup> ```elixir Elixir theme={null} # lib/my_app/probes/my_probe.ex defmodule MyApp.MyProbe do def call do Appsignal.set_gauge("database_size", 10) end end ``` </CodeGroup> Now you can register this probe in the start function of your OTP app. <CodeGroup> ```elixir Elixir theme={null} Appsignal.Probes.register(:my_probe, &MyApp.MyProbe.call/0) ``` </CodeGroup> ### Stateful probes As of version `2.2.8` of the AppSignal Elixir package, probes can pass state between runs. If your probe takes an argument, the return value of the last run will be passed as the value for that argument in the following run. An initial state to be used for the probe's first run can be provided as the third argument to `Appsignal.Probes.register`. If it is not provided, the initial state will be `nil`. <CodeGroup> ```elixir Elixir theme={null} Appsignal.Probes.register(:stateful_probe, fn minutes -> Appsignal.set_gauge("uptime_minutes", minutes) minutes + 1 end, 0) ``` </CodeGroup> Or, as a module based function: <CodeGroup> ```elixir Elixir theme={null} # lib/my_app/probes/my_probe.ex defmodule MyApp.MyProbe do def call(minutes) do Appsignal.set_gauge("uptime_minutes", minutes) minutes + 1 end end ``` </CodeGroup> Which you can then register as: <CodeGroup> ```elixir Elixir theme={null} Appsignal.Probes.register(:stateful_probe, &MyApp.MyProbe.call/1, 0) ``` </CodeGroup> ## Registering probes Probes can be registered with the `register` method on the `Appsignal.Probes` module. This method accepts three arguments. * `key` - This is the key/name of the probe. This will be used to identify the probe in case an error occurs while executing the probe (which will be logged to the [appsignal.log file](/support/debugging#logs)) and to [override an existing probe](#overriding-default-probes). * `probe` - This is one of the [supported probe types](#creating-probes) that should be called every minute to collect metrics. * `state` - This is the initial state that will be passed to your probe. If your probe does not take state as an argument, then this argument has no effect. It is an optional argument, and its default value is `nil`. To add a probe, register it in your application's `start/2` function, just before the supervisor is started. In a Phoenix app this will look like this: <CodeGroup> ```elixir Elixir theme={null} # lib/my_app/application.ex def start(_type, _args) do children = [ MyApp.Repo, MyAppWeb.Endpoint, ] Appsignal.Probes.register(:my_probe, &MyProbe.call/0) opts = [strategy: :one_for_one, name: Weekmenu.Supervisor] Supervisor.start_link(children, opts) end ``` </CodeGroup> ## Overriding default probes AppSignal ships with default probes for certain [integrations](/elixir/integrations/). If for any reason this probe does not function properly or requires some additional configuration for your use case, you can override the default probe by registering a new probe with the same key. <CodeGroup> ```elixir Elixir theme={null} # lib/my_app/application.ex Appsignal.Probes.register(:erlang, fn() -> # Do things end) ``` </CodeGroup> Overriding probes will log a debug message in the [appsignal.log file](/support/debugging#logs) which can help to detect if a probe is correctly overridden. # Mix tasks Source: https://docs.appsignal.com/elixir/instrumentation/mix_tasks AppSignal for Elixir doesn't automatically instrument mix tasks, but you can set up manual instrumentation and error handling using [custom instrumentation](/elixir/instrumentation/). ## Starting and stopping AppSignal Since Mix tasks don't automatically start applications, you'll need to explicitly start the `:appsignal` application in your task: <CodeGroup> ```elixir Elixir theme={null} Application.ensure_all_started(:appsignal) ``` </CodeGroup> To make sure AppSignal has enough time to flush data to its agent, call `Appsignal.Nif.stop/0` at the end of your task, which blocks until the extension has had enough time to flush the sent payloads to the agent before stopping. ## Catching errors To wrap errors in your task to be sent to AppSignal, add a `rescue` block to catch errors from your code. Pass the captured exception to `Appsignal.send_error/3` to report it to AppSignal. Add an `after` clause to your `rescue` block to call `Appsignal.Nif.stop/0`. <CodeGroup> ```elixir Elixir theme={null} defmodule Mix.Tasks.Rescue do use Mix.Task def run(_) do {:ok, _} = Application.ensure_all_started(:appsignal) raise "rescue!" catch kind, reason -> stack = __STACKTRACE__ Appsignal.send_error(kind, reason, stack) reraise(reason, stack) after Appsignal.Nif.stop :timer.sleep(35_000) # For one-off containers end end ``` </CodeGroup> **Note:** A sleep of 35 seconds was added to the end of the Mix task. This is recommended for tasks that are run on one-off containers. When the task completes the process stops. The `Appsignal.Nif.stop/0` function call flushes all the transaction data currently in the AppSignal extension to our agent. There it is [transmitted on a 30 second interval](/appsignal/how-appsignal-operates#agent). The one-off container may have exited before that time. To ensure the data is still transmitted, it needs to wait for 35 seconds. ## Measuring performance To measure performance in your task, start and stop a transaction manually and add events using the instrumentation helpers, like described in the [custom helper instrumentation](/elixir/instrumentation/instrumentation#helper-transactions). <CodeGroup> ```elixir Elixir theme={null} defmodule Mix.Tasks.Instrument do use Mix.Task def run(_) do {:ok, _} = Application.ensure_all_started(:appsignal) Appsignal.instrument(fn span -> span |> Appsignal.Span.set_namespace("background_job") |> Appsignal.Span.set_name("Mix.Tasks.Instrument") Appsignal.instrument(fn span -> Appsignal.Span.set_name("task.instrumented") :timer.sleep(1_000) end) end) Appsignal.Nif.stop() :timer.sleep(35_000) # For one-off containers end end ``` </CodeGroup> # Elixir integrations Source: https://docs.appsignal.com/elixir/integrations AppSignal for Elixir currently supports the following Elixir integrations: * [Absinthe](/elixir/integrations/absinthe) * [Phoenix](/elixir/integrations/phoenix) * [Plug](/elixir/integrations/plug) * [Ecto](/elixir/integrations/ecto) * [Erlang](/elixir/integrations/erlang) * [Finch](/elixir/integrations/finch) * [HTTPoison](/elixir/integrations/httpoison) * [Oban](/elixir/integrations/oban) * [Tesla](/elixir/integrations/tesla) If you want to integrate with AppSignal manually, please read our [integration guide](/elixir/instrumentation/integrating-appsignal). ## Third-party integrations The following integrations have been developed for AppSignal for Elixir by third-parties: * [Ash](https://hexdocs.pm/ash_appsignal/getting-started-with-ash-appsignal.html) # Absinthe Source: https://docs.appsignal.com/elixir/integrations/absinthe <VersionRequirements /> The AppSignal for Elixir package instruments operations performed by [Absinthe](https://github.com/absinthe-graphql/absinthe), a GraphQL toolkit for Elixir, using the Telemetry library. AppSignal will automatically recognize operations executed by Absinthe and wrap them into a `call.graphql` event on your Event Timeline, like in the below example: <img alt="Screenshot of Absinthe executed events being shown in the Events Timeline" /> Combined with our [Ecto integration](/elixir/integrations/ecto), AppSignal's Absinthe integration helps provide a comprehensive overview of what's happening when a GraphQL query is executed. ## Automatic Instrumentation Absinthe is automatically instrumented, requiring no configuration. To disable the Absinthe instrumentation, set the `instrument_absinthe` [config option](/elixir/configuration/options#option-instrument_absinthe) to `false`. # Instrumenting Ecto queries Source: https://docs.appsignal.com/elixir/integrations/ecto AppSignal uses Ecto’s Telemetry instrumentation to gain information about queries ran in your app by attaching a handler that gets called whenever a query is executed. ## Automatic instrumentation The Ecto instrumentation automatically hooks into your Ecto repos if the `:otp_app` configuration is configured to your app's OTP app name. The installer automatically configures this for you. <CodeGroup> ```elixir Elixir theme={null} config :appsignal, :config, otp_app: :my_app, # Set this to the name of your OTP app name: "My app", push_api_key: "your-api-key", env: Mix.env ``` </CodeGroup> The integration then uses your app's configuration to find out which repos are configured, as your app will have a configuration line like this in `config/config.exs`: <CodeGroup> ```elixir Elixir theme={null} config :my_app, ecto_repos: [AppsignalPhoenixExample.Repo] ``` </CodeGroup> ### Disable automatic instrumentation <Compatibility /> To disable automatic Ecto instrumentation, set [the `instrument_ecto` config option](/elixir/configuration/options#option-instrument_ecto) to `false`. ## Instrumenting Ecto preloads <Compatibility /> Since Ecto preload queries internally use several Elixir processes to carry out the different database queries involved, some manual changes to your codebase are necessary for AppSignal to properly instrument them. At the top of your Ecto repo module, replace `use Ecto.Repo` with `use Appsignal.Ecto.Repo`, as in the following example: <CodeGroup> ```elixir Elixir theme={null} defmodule MyApp.Repo do # replace `use Ecto.Repo` with `use Appsignal.Ecto.Repo` use Appsignal.Ecto.Repo, otp_app: :my_app, adapter: Ecto.Adapters.Postgres end ``` </CodeGroup> If your Ecto repo module has its own implementation of the `default_options/1` function, make sure to call `super` within it to merge its default options with those of AppSignal's Ecto repo instrumentation: <CodeGroup> ```elixir Elixir theme={null} defmodule MyApp.Repo do use Appsignal.Ecto.Repo, ... def default_options(operation) do super(operation) ++ [ # ... your default options here ... ] end end ``` </CodeGroup> ## Manual handler attachment For repos that aren't listed in the `:ecto_repos` configuration, you can attach a handler manually when starting your app’s supervisor. In most applications, this is done in your application’s `start/2` function. <CodeGroup> ```elixir Elixir theme={null} def start(_type, _args) do children = [ AppsignalPhoenixExample.Repo, AppsignalPhoenixExampleWeb.Endpoint ] Appsignal.Ecto.attach(:my_otp_app, MyApp.Repo) opts = [strategy: :one_for_one, name: AppsignalPhoenixExample.Supervisor] Supervisor.start_link(children, opts) end ``` </CodeGroup> In this example, we’ve attached the Telemetry handler to our Phoenix application by calling `Appsignal.Ecto.attach/2`. The first argument is the name of the OTP app that the repo belongs to, and the second argument is the repo's module. ## Metrics <Compatibility /> In addition to instrumenting your Ecto queries, AppSignal for Elixir collects metrics about your Ecto repos' performance: * `ecto_query_time`: The time the database spends executing each query, tagged by `repo` and `hostname`, and for each table by `repo` and `source`. * `ecto_queue_time`: The time spent waiting for a database connection from the pool, tagged by `repo` and `hostname`. * `ecto_decode_time`: The time spent decoding query results into Elixir terms, tagged by `repo` and `hostname`, and for each table by `repo` and `source`. * `ecto_idle_time`: The time the connection sat idle in the pool before being checked out, tagged by `repo` and `hostname`. * `ecto_total_time`: The sum of queue, query, and decode time, tagged by `repo` and `hostname`, and for each table by `repo` and `source`. AppSignal uses these metrics to create the Ecto magic dashboard, which shows key insights into your Ecto repos' performance: <Frame> <img alt="Magic dashboard showing key Ecto metrics" /> </Frame> # Erlang Source: https://docs.appsignal.com/elixir/integrations/erlang The AppSignal for Elixir package integrates with the Erlang VM to provide metrics not just about your app but the virtual machine it's running in. ## Minutely probe Since AppSignal Elixir package `1.10.1` and up a [minutely probe](/elixir/instrumentation/minutely-probes) is activated by default. Once we detect these metrics we'll add a [magic dashboard](https://blog.appsignal.com/2019/03/27/magic-dashboards.html) to your apps. This probe will report the following [metrics](/metrics/custom) grouped by `hostname` tag: * `erlang_io` - gauge * Tag `type`: * `input` * `output` * `erlang_schedulers` - gauge * Tag `type`: * `total` * `online` * `erlang_processes` - gauge * Tag `type`: * `limit` * `count` * `erlang_memory` - gauge * Tag `type`: * `total` * `processes` * `processes_used` * `system` * `atom` * `atom_used` * `binary` * `code` * `ets` * `erlang_atoms` - gauge * Tag `type`: * `limit` * `count` * `erlang_scheduler_utilization` - gauge (since version `2.2.8`) * Tag `type`: * `normal` * Tag `id`: the ID of the scheduler ### Configuration This probe listens to the [`hostname` config option](/elixir/configuration/options#option-hostname) for the hostname tag added to all its metrics. If none is set it will try to detect it automatically. Use the `hostname` config option to set the hostname if you want to change the detected hostname. # Finch Source: https://docs.appsignal.com/elixir/integrations/finch <VersionRequirements /> The AppSignal for Elixir package instruments HTTP requests performed by [Finch](https://github.com/sneako/finch). Finch is a performance-focused HTTP client built on top of [Mint](https://blog.appsignal.com/2022/10/20/appsignal-for-elixir-now-supports-finch.html#:~:text=on%20top%20of-,Mint,-%2C%20Elixir%27s%20low%2Dlevel), Elixir's low-level HTTP client library, and has built-in support for request telemetry. Finch handles the opening and closing of connections, making it easier for you to add HTTP requests to your application. AppSignal will automatically recognize external requests executed by Finch and wrap them into a `request.finch` event on your Event Timeline, like in the below example: <img alt="Event Timeline" /> In the Event Timeline, you'll see how much time Finch spends making external API requests. This data may help inform you to move the API requests to a background job or introduce caching to help speed up performance and limit unnecessary API requests. ## Automatic Instrumentation <Tip> The `instrument_finch` config option was added in version `2.5.1` of the AppSignal for Elixir integration. </Tip> Finch is automatically instrumented, requiring no configuration. To disable the Finch instrumentation, set [the `instrument_finch` config option](/elixir/configuration/options#option-instrument_finch) to `false`. # HTTPoison Source: https://docs.appsignal.com/elixir/integrations/httpoison <VersionRequirements /> The AppSignal for Elixir package instruments HTTP requests performed by [HTTPoison](https://github.com/edgurgel/httpoison). HTTPoison is a popular HTTP client for Elixir. Unlike Finch and Tesla, HTTPoison does not emit telemetry events, so AppSignal cannot automatically instrument it. Instead, AppSignal provides wrapper modules that you opt into: `Appsignal.HTTPoison` as a drop-in client, and `Appsignal.HTTPoison.Base` for custom client modules. The response and error structs (`%HTTPoison.Response{}`, `%HTTPoison.Error{}`, ...) are HTTPoison's own types and are returned unchanged. AppSignal will wrap requests executed via `Appsignal.HTTPoison` as `request.httpoison` events on your performance samples' event timeline, allowing you to see how much time HTTPoison spends making external API requests. This data may help inform you to move the API requests to a background job, or to introduce caching to help speed up performance and limit unnecessary API requests. ## Configuration HTTPoison instrumentation is opt-in. Choose the approach that best fits your application. ### Using Appsignal.HTTPoison directly Call `Appsignal.HTTPoison` instead of `HTTPoison` to make instrumented requests. Pattern-match on `%HTTPoison.Response{...}` and `%HTTPoison.Error{...}` as normal β€” these are HTTPoison's own struct types, returned unchanged: <Warning> Do not use `alias Appsignal.HTTPoison`. This would shadow the `HTTPoison` module name, causing `%HTTPoison.Response{}` and `%HTTPoison.Error{}` pattern matches to fail. </Warning> <CodeGroup> ```elixir Elixir theme={null} defmodule MyAppWeb.PageController do use MyAppWeb, :controller def index(conn, _params) do case Appsignal.HTTPoison.get("https://api.example.com/users") do {:ok, %HTTPoison.Response{status_code: 200, body: body}} -> render(conn, :index, users: body) {:ok, %HTTPoison.Response{status_code: status}} -> conn |> put_status(status) |> text("Error") {:error, %HTTPoison.Error{reason: reason}} -> conn |> put_status(500) |> text("Error: #{reason}") end end end ``` </CodeGroup> ### Custom client modules If you use a custom HTTP client module based on `HTTPoison.Base`, replace `use HTTPoison.Base` with `use Appsignal.HTTPoison.Base`. No further changes are needed β€” inside the module, you can call methods like `get/1` and `post/3`, and match on HTTPoison's response and error structs as normal: <CodeGroup> ```elixir Elixir theme={null} defmodule MyApp.ApiClient do # replace `use HTTPoison.Base` with `use Appsignal.HTTPoison.Base` use Appsignal.HTTPoison.Base def process_url(url) do "https://api.example.com" <> url end def users do case get("/users") do {:ok, %HTTPoison.Response{status_code: 200, body: body}} -> {:ok, body} {:ok, %HTTPoison.Response{status_code: status}} -> {:error, status} {:error, %HTTPoison.Error{reason: reason}} -> {:error, reason} end end end ``` </CodeGroup> All requests made through your custom client will then be instrumented automatically. If your module overrides `request/5`, make sure to call `super` to preserve the instrumentation: <CodeGroup> ```elixir Elixir theme={null} defmodule MyApp.ApiClient do use Appsignal.HTTPoison.Base def request(method, url, body, headers, options) do # ... custom logic here ... super(method, url, body, headers, options) end end ``` </CodeGroup> # Oban Source: https://docs.appsignal.com/elixir/integrations/oban <VersionRequirements /> The AppSignal for Elixir package instruments jobs performed by [Oban](https://oban.pro) workers, and collects metrics about your jobs' performance. Oban is a job queueing and processing system for Elixir, based on PostgreSQL and Ecto. You can use Oban to schedule jobs to be ran in the background. ## Automatic Instrumentation Oban support is automatically instrumented, requiring no configuration. To disable the Oban instrumentation, set [the `instrument_oban` config option](/elixir/configuration/options#option-instrument_oban) to `false`. <Note> πŸ”Ž The `instrument_oban` config option was added in version `2.5.1` of the AppSignal for Elixir integration. </Note> ## Error Reporting By default, the Oban instrumentation will create an error sample whenever one of your workers fails to process a job, either by returning an `{:error, _}` tuple or by throwing an exception. If you only wish to send errors to AppSignal when the failure causes the job to be discarded, that is, once it's reached its maximum retry attempts, set [the `report_oban_errors` config option](/elixir/configuration/options#option-report_oban_errors) to `"discard"`. Set it to `"none"` to never send Oban job errors to AppSignal. <Tip> The `report_oban_errors` config option was added in version `2.5.1` of the AppSignal for Elixir integration. If using Oban version `2.3.1` or below, the information about the state of the job is not available, and the `"discard"` option will behave like `"all"`. </Tip> ## Performance and Error Samples AppSignal will create performance samples out of jobs executed by your Oban workers: <img alt="Performance sample from an Oban job execution" /> It will also notify errors that cause your workers to fail while processing a job: <img alt="Error sample from an Oban job execution" /> Within the performance and error samples, the tags will contain information about the job: * Job ID, queue, worker and priority * Number of previous attempts * Job state and result after execution Any tags or metadata values added to the job will also be present as tags in the sample, allowing you to filter the samples for a specific tag. You will also be able to see when an Oban job is inserted in the event timeline of your application's performance samples: <img alt="Event timeline showing an Oban job insertion" /> <Note> πŸ”Ž Some features are only available in certain Oban versions: * **2.1.0+:** Tags * **2.3.1+:** Metadata values and job priority * **2.4.0+:** Job state after execution * **2.5.0+:** Job result after execution * **2.11.0+:** Job insertion event To make use of all the features described above, upgrade to the latest Oban version. </Note> ## Metrics In addition to the performance and error samples, AppSignal for Elixir will collect metrics about the performance of your Oban jobs: * `oban_job_duration`: the duration of the jobs processed, tagged by the job's worker, queue and status. * `oban_job_queue_time`: the time spent by jobs waiting in the queue, tagged by queue. * `oban_job_count`: the amount of jobs processed, tagged by the job's worker, queue and status. Using this metrics, AppSignal will automatically create the Oban magic dashboard, which provides key insights into your Oban system's performance: <img alt="Magic dashboard showing key Oban metrics" /> # Integrating AppSignal into Phoenix Source: https://docs.appsignal.com/elixir/integrations/phoenix The AppSignal for Elixir package integrates with Phoenix. To set up the integration, please follow our [installation guide](/elixir/installation). This page will describe further ways of configuring AppSignal for the [Phoenix framework][phoenix]. To add more custom instrumentation to your Phoenix application, read the [Elixir instrumentation](/elixir/instrumentation) documentation. More information can be found in the [AppSignal Hex package documentation][hex-appsignal]. ## Installation 1. The AppSignal instrumentation for Phoenix is part of a separate package, which depends on the primary `appsignal` package. Add the `appsignal_phoenix` package to your `mix.exs` file. <CodeGroup> ```elixir Elixir theme={null} # mix.exs defmodule AppsignalPhoenixExample.MixProject do # ... defp deps do [ {:phoenix, "~> 1.5.3"}, {:appsignal_phoenix, "~> 2.0"} # ... ] end end ``` </CodeGroup> 2. Then run `mix deps.get`. 3. Then run `mix appsignal.install YOUR_PUSH_API_KEY`. After installing and configuring, the AppSignal for Phoenix package automatically starts instrumenting HTTP requests, meaning no further setup is necessary. To gain deeper insights, AppSignal can be set up to instrument channels and live views. ## Channels ### Channel instrumentation with a channel's handle Incoming channel requests can be instrumented by wrapping the code in your `handle_in/3` functions with `Appsignal.Phoenix.Channel.instrument/5`: <CodeGroup> ```elixir Elixir theme={null} defmodule AppsignalPhoenixExampleWeb.RoomChannel do use Phoenix.Channel # ... def handle_in("new_msg", %{"body" => body} = params, socket) do Appsignal.Phoenix.Channel.instrument(__MODULE__, "new_msg", params, socket, fn -> broadcast!(socket, "new_msg", %{body: body}) {:noreply, socket} end) end end ``` </CodeGroup> Alternatively, you can use function decorators to instrument channels. While less flexible than the instrumentation function, decorators minimize the amount of code you have to add to your application's channels. <CodeGroup> ```elixir Elixir theme={null} defmodule SomeApp.MyChannel do use Appsignal.Instrumentation.Decorators @decorate channel_action() def handle_in("ping", _payload, socket) do # your code here.. end end ``` </CodeGroup> Channel events will be displayed under the "Background jobs" tab, showing the channel module and the action argument that you entered. ## LiveView There are two different ways to instrument live views. You can either use our automatic telemetry handlers, or you can manually instrument your live view handlers with our helper functions. ### Automatic telemetry handlers <Tip> **Note**: The LiveView Telemetry integration is available from AppSignal for Phoenix version `2.1.0` onward. </Tip> AppSignal's LiveView Telemetry integration automatically instruments live view events. To set it up, call `Appsignal.Phoenix.LiveView.attach/0` to attach the LiveView Telemetry handlers. We recommend calling this function from your app's `application.ex`: <CodeGroup> ```elixir Elixir theme={null} defmodule AppsignalPhoenixExample.Application do # ... def start(_type, _args) do Appsignal.Phoenix.LiveView.attach() # <--- attach the LiveView Telemetry handlers children = [ # Start the Ecto repository AppsignalPhoenixExample.Repo, # Start the Telemetry supervisor AppsignalPhoenixExampleWeb.Telemetry, # Start the PubSub system {Phoenix.PubSub, name: AppsignalPhoenixExample.PubSub}, # Start the Endpoint (http/https) AppsignalPhoenixExampleWeb.Endpoint # Start a worker by calling: AppsignalPhoenixExample.Worker.start_link(arg) # {AppsignalPhoenixExample.Worker, arg} ] # See https://hexdocs.pm/elixir/Supervisor.html # for other strategies and supported options opts = [strategy: :one_for_one, name: AppsignalPhoenixExample.Supervisor] Supervisor.start_link(children, opts) end end ``` </CodeGroup> AppSignal will now automatically instrument all `mount`, `handle_event` and `handle_param` events under the `live_view` namespace, meaning you'll receive both performance and error insights into your live views. ### Manual helper functions <Tip> If you've already configured the automatic telemetry instrumentation above, you do not need to manually instrument your live view handlers. </Tip> <Tip> **Note**: The LiveView helper functions are available from AppSignal for Elixir version `1.13.0` onward. </Tip> A LiveView action can also be manually instrumented by wrapping its contents in a `Appsignal.Phoenix.LiveView.instrument/4` block. Given a live view that updates its own state every second, we can add AppSignal instrumentation by wrapping both the mount/2 and handle\_info/2 functions with a `Appsignal.Phoenix.LiveView.instrument`/4 call: <CodeGroup> ```elixir Elixir theme={null} defmodule AppsignalPhoenixExampleWeb.ClockLive do use Phoenix.LiveView import Appsignal.Phoenix.LiveView, only: [instrument: 4] def render(assigns) do AppsignalPhoenixExampleWeb.ClockView.render("index.html", assigns) end def mount(_session, socket) do # Wrap the contents of the mount/2 function with a call to # Appsignal.Phoenix.LiveView.instrument/4 instrument(__MODULE__, "mount", socket, fn -> :timer.send_interval(1000, self(), :tick) {:ok, assign(socket, state: Time.utc_now())} end) end def handle_info(:tick, socket) do # Wrap the contents of the handle_info/2 function with a call to # Appsignal.Phoenix.LiveView.instrument/4: instrument(__MODULE__, "tick", socket, fn -> {:ok, assign(socket, state: Time.utc_now())} end) end end ``` </CodeGroup> Calling one of these functions in your app will now automatically create a sample that's sent to AppSignal. These are displayed under the `:live_view` namespace. ## Instrumentation for included Plugs Exceptions in included Plugs are automatically caught by AppSignal, but performance samples need to be set up manually using the custom instrumentation helpers or decorators. See the [Plug](/elixir/integrations/plug#instrumentation-for-included-plugs) documentation for more information. ## Custom instrumentation [Add custom instrumentation](/elixir/instrumentation/instrumentation) to keep track of more complex code and get more complete breakdowns of slow requests. [phoenix]: http://www.phoenixframework.org/ [hex-appsignal]: https://hexdocs.pm/appsignal/ # Integrating AppSignal into Plug Source: https://docs.appsignal.com/elixir/integrations/plug <Tip> **Note**: Support for custom namespaces was added in version 1.3.0 of the AppSignal for Elixir package. </Tip> The AppSignal for Elixir package integrates with Plug. To set up the integration, please follow our [installation guide](/elixir/installation). This page describes how to set up AppSignal in a Plug application, and how to add instrumentation for events within requests. For more information about custom instrumentation, read the [Elixir instrumentation](/elixir/instrumentation) documentation. More information can be found in the [AppSignal Hex package documentation][hex-appsignal]. ## Installation The AppSignal instrumentation for Plug is part of a separate package, which depends on the primary `appsignal` package. Add the `appsignal_plug` package to your `mix.exs` file. <CodeGroup> ```elixir Elixir theme={null} # mix.exs defmodule AppsignalPlugExample.MixProject do # ... defp deps do [ {:plug, "~> 1.0"}, # Or plug_cowboy ~> 2.0 {:appsignal_plug, "~> 2.0"} # ... ] end end ``` </CodeGroup> If you're already using our `appsignal_phoenix` package, it's not necessary to add the `appsignal_plug` package as it's already a dependency of the `appsignal_phoenix` package. See also our [Phoenix integration guide](/elixir/installation/umbrella#phoenix). ## Incoming HTTP requests We'll start out with a small Plug app that accepts `GET` requests to `/` and returns a welcome message. To start logging HTTP requests in this app, we'll use the `Appsignal.Plug` module. <CodeGroup> ```elixir Elixir theme={null} defmodule AppsignalPlugExample do use Plug.Router use Appsignal.Plug # <- Add this plug :match plug :dispatch get "/" do send_resp(conn, 200, "Welcome") end end ``` </CodeGroup> This will create a transaction for every HTTP request which is performed on the endpoint. ## Custom instrumentation Although `Appsignal.Plug` will start transactions for you, it won't instrument events in your app just yet. To do that, we need to add some custom instrumentation. This example app looks like the one we used before, but it has a slow function (aptly named `slow/0`) we'd like to add instrumentation for. To do that, we need to use the `Appsignal.instrument/2-3` helper in our called function: <CodeGroup> ```elixir Elixir theme={null} defmodule AppsignalPlugExample do use Plug.Router plug :match plug :dispatch get "/" do slow() send_resp(conn, 200, "Welcome") end defp slow do Appsignal.instrument("slow", fn -> :timer.sleep(1000) end) end use Appsignal.Plug end ``` </CodeGroup> This will add an event for the `slow/0` function to the current transaction whenever it's called. For more information about custom instrumentation, read the [Elixir instrumentation](/elixir/instrumentation) documentation. ## Instrumentation for included Plugs Exceptions in included Plugs are automatically caught by AppSignal, but performance samples need to be set up manually using the custom instrumentation helpers or decorators. ### Plug instrumentation with decorators To add instrumentation to Plugs, use the `Appsignal.instrument/2` function: <CodeGroup> ```elixir Elixir theme={null} defmodule SlowPlugWithDecorators do import Plug.Conn def init(opts), do: opts def call(conn, _) do Appsignal.instrument("SlowPlugWithDecorators", fn -> :timer.sleep(1000) conn end) end end ``` </CodeGroup> [hex-appsignal]: https://hexdocs.pm/appsignal/ # Tesla Source: https://docs.appsignal.com/elixir/integrations/tesla <VersionRequirements /> The AppSignal for Elixir package instruments HTTP requests performed by [Tesla](https://github.com/elixir-tesla/tesla). Tesla is a flexible HTTP client library for Elixir. It can use multiple middlewares and adapters to modify and perform HTTP request, and it has built-in support for request telemetry. After configuring Tesla's Telemetry middleware, AppSignal will recognize requests executed via Tesla and show them as `request.tesla` events on your performance samples' Event Timeline. In the Event Timeline, you'll see how much time Tesla spends making external API requests. This data may help inform you to move the API requests to a background job or introduce caching to help speed up performance and limit unnecessary API requests. In the Slow API Requests performance view, you'll be able to see aggregated throughput and average times for different kinds of HTTP requests. Follow the instructions in the [Path Params Grouping](#path-params-grouping) section in order to improve the information shown in this view. ## Configuration Add the `Tesla.Middleware.Telemetry` middleware to your module or client's middleware chain, **before any other middlewares**: <CodeGroup> ```elixir Elixir theme={null} defmodule MyAPIClient do use Tesla plug Tesla.Middleware.Telemetry # ... plug other middlewares here, **after** the Telemetry middleware end ``` </CodeGroup> <CodeGroup> ```elixir Elixir theme={null} client = Tesla.client([ Tesla.Middleware.Telemetry, # ... add other middlewares here, **after** the Telemetry middleware ]) ``` </CodeGroup> <Tip> If using the Finch adapter for Tesla, you should [disable AppSignal's Finch instrumentation](/elixir/integrations/finch#automatic-instrumentation) by setting the `instrument_finch` configuration option to `false`. </Tip> ## Enhanced Grouping By default, the AppSignal instrumentation for Tesla will group requests by the domain name they're performed against. The path of the request will not be shown in AppSignal. However, by using certain Tesla middlewares, it's possible to add more information about the request. The following sections describe each middleware's behaviour separately, but it is also possible to use them together. ### Base URL Grouping When using the `BaseUrl` middleware, the base URL provided, including its path, will be used for grouping, providing you with some additional insight into the target of the HTTP requests performed by Tesla: <CodeGroup> ```elixir Elixir theme={null} defmodule MyAPIClient do use Tesla plug Tesla.Middleware.Telemetry # make sure Telemetry appears **before** any other middleware! plug Tesla.Middleware.BaseUrl, "https://api.example.com/v2/users" def user_comments(id) do get("/#{id}/comments") end end ``` </CodeGroup> In the above example, requests performed by this client will be shown in the sample's Event Timeline and in the Slow API Requests performance view as `GET https://api.example.com/v2/users`, instead of just `GET https://api.example.com`, providing additional information about the requests that are being performed. ### Path Params Grouping When using the `PathParams` middleware, the URL given to Tesla for the request will be a template, with path parameters being passed separately: <CodeGroup> ```elixir Elixir theme={null} defmodule MyAPIClient do use Tesla plug Tesla.Middleware.Telemetry # make sure Telemetry appears **before** any other middleware! plug Tesla.Middleware.PathParams def user_comments(id) do params = [user: id] get("https://api.example.com/v2/users/:user/comments", opts: [path_params: params]) end end ``` </CodeGroup> When `PathParams` is used, the URL template will be shown in AppSignal. Requests will appear as `GET https://api.example.com/v2/users/:user/comments` in the sample's Event Timeline and in the Slow API Requests performance view, providing you with a detailed view of each request type that your client performs. ## Disable Tesla Instrumentation To disable the Tesla instrumentation, set [the `instrument_tesla` config option](/elixir/configuration/options#option-instrument_tesla) to `false`. # Elixir Releases Source: https://docs.appsignal.com/elixir/releases AppSignal’s Elixir integration does not require any extra configuration for apps deployed through [Distillery](https://github.com/bitwalker/distillery) or Elixir 1.9’s releases feature, but the agent needs to be built on a machine with the same architecture as the machine you'll be hosting your application on. AppSignal for Elixir doesn't support cross-compilation at this time. ## Debugging releases Since released applications can be more difficult to debug, here are the steps we take when a support request for a deployed Elixir application comes in. ### Development mode First and foremost, we check if the problem is caused by the release by making sure everything works in development, on your local machine. Start your app locally, on your development machine, in the development environment: <CodeGroup> ```bash Bash theme={null} $ mix phx.server ``` </CodeGroup> Request some pages in your app, and sign into AppSignal to see if any performance samples come in. If possible, trigger an exception in one of your app’s controllers to see if it ends up on your errors page too. <Tip> **Note**: Running AppSignal in your development environment will create a β€œdev” environment on your account overview in AppSignal, where the data will appear. </Tip> If you don’t receive any data, double-check the steps in the [installation guide](/elixir/installation) and the [Phoenix](/elixir/integrations/phoenix) guide to make sure everything in your app is set up properly. If the install guide doesn’t show any missed steps, run the [diagnose command](/elixir/command-line/diagnose#usage) (still on your local machine): <CodeGroup> ```bash Bash theme={null} $ mix appsignal.diagnose --send-report ``` </CodeGroup> The diagnose command runs diagnostics, and the `--send-report` option sends the report to our servers. Then, contact [support](mailto:support@appsignal.com) with the support token you receive at the end of the report. ### Diagnose If everything works locally in development, but your production install isn’t yet, run the diagnose command on your release binary. <CodeGroup> ```bash Bash theme={null} # Elixir releases $ bin/your_app eval ":appsignal_tasks.diagnose()" # Distillery $ bin/your_app command appsignal_tasks diagnose ``` </CodeGroup> When asked to send the report to AppSignal, choose `Y`. Then, contact [support](mailto:support@appsignal.com) with the support token you receive at the end of the report. # Why a NIF? Source: https://docs.appsignal.com/elixir/why-nif The AppSignal for Elixir integration relies on [a NIF](http://erlang.org/doc/man/erl_nif.html) that calls out to a library to do the heavy lifting, written in [Rust](https://www.rust-lang.org). Its job is to receive data from the Elixir app, normalize it and write it to a separate agent process over a Unix socket. The agent then sends the data to AppSignal.com periodically for further processing. See our [how AppSignal operates](/appsignal/how-appsignal-operates) page more information about how our agent works. While using a NIF has inherent risks, using one in this case has several advantages: 1. Overhead is very low. The functions in the NIF do nothing more than receive data and send it to a worker thread, so that the C function can return immediately. It's designed to be as fast as possible while having very little impact on the calling thread, and generate minimal garbage collection load. 2. It allows the use of the same library and agent used by AppSignal for [Ruby](/ruby), which runs on thousands of production servers all over the world. It's battle tested technology, processing a combined 1 billion requests *per day* (November 2016). 3. The library and agent are written in Rust, and its primary design considerations were (and remain) robustness and performance. Internally, the AppSignal NIF works as follows: it fork/execs a separate agent process, to which a worker thread in the NIF sends its data over a Unix socket. All I/O and processing in the NIF is asynchronous, so calls to its functions will never hold up the scheduler. In the very unlikely event that something in the extension panics, the extension disables itself without bringing down the host process. While doing native Elixir protobufs to communicate directly with the agent makes more sense from a BEAM standpoint, using a NIF enables the use of a single library. This decreases potential issues because of the volume of testing and fine-tuning that has already happened. By focusing on a single code base, AppSignal can guarantee the highest quality for all of its customers across all supported languages. # Errors Source: https://docs.appsignal.com/errors How AppSignal tracks, groups, and alerts on errors, and where to report handled exceptions. AppSignal captures the exceptions your application raises, groups them so they are easy to triage, and alerts you when something needs attention. Errors are tightly coupled to traces: an error usually happens inside a request, background job, or script run, and the surrounding trace gives you the timing and context you need to debug it. ## How AppSignal groups errors When your application reports an exception, AppSignal groups it into an **issue** with other occurrences of the same error type on the same action and namespace. A single bug that fires thousands of times becomes one issue to triage, not thousands of separate alerts. Each issue keeps a set of **samples**: representative occurrences with the full backtrace, request metadata (such as hostname, revision, and request path), and any tags you add. ## Triage and notifications Each issue can be assigned to a team member, given a state and a severity, and configured with its own notification settings. AppSignal notifies you through your configured channels (email, Slack, and other integrations) when a new error is detected. ## Namespaces Errors are grouped by namespace, so you can separate web requests from background jobs. The default namespaces are Web and Background, and you can configure custom ones. See [Namespaces](/guides/namespaces) for details. ## Alerting on error rates Beyond per-error notifications, [anomaly detection](/anomaly-detection) can alert you when the error rate for an application or namespace crosses a threshold you set. ## Reporting handled exceptions If you catch an exception yourself, you can still report it to AppSignal with the helper methods provided by your SDK. The exact helper names vary by SDK, but the goal is the same: keep the error attached to the trace, or send it with useful context. * Ruby: [`report_error`, `set_error`, and `send_error`](/ruby/instrumentation/exception-handling) * Elixir: [`Appsignal.set_error/2` and `Appsignal.send_error/3`](/elixir/instrumentation/exception-handling) * Node.js: [`setError()` and `sendError()`](/nodejs/3.x/instrumentation/exception-handling) * Python: [`set_error` and `send_error`](/python/instrumentation/exception-handling) * PHP: [Exception handling](/php/exception-handling) * Front-end JavaScript: [Error handling](/front-end/error-handling) ## Add debugging context To make errors easier to investigate, add more context with: * [Tagging](/application/tagging) * [Backtrace links](/application/backtrace-links) * [Performance / tracing](/performance-tracing) # Frequently Asked Questions Source: https://docs.appsignal.com/faq There's no such thing as a stupid question. On this page, you'll find the answers to the ones we're asked most frequently. If you need further support, please check out our [support page](/support/) ## Contents * [Getting Started](#getting-started) * [I Need Help Getting Started. Where Do I Begin?](#i-need-help-getting-started-where-do-i-begin) * [AppSignal Libraries](#appsignal-libraries) * [What Programming Languages Does AppSignal Support?](#what-programming-languages-does-appsignal-support) * [Filtering Data](#filtering-data) * [How Do I Ignore Actions in My Application?](#how-do-i-ignore-actions-in-my-application) * [How Do I Ignore Errors in My Application?](#how-do-i-ignore-errors-in-my-application) * [How Do I Filter Data That's Sent to AppSignal?](#how-do-i-filter-data-that’s-sent-to-appsignal) * [How Do I Add Additional Instrumentation to My Application?](#how-do-i-add-additional-instrumentation-to-my-application) * [What Is the Difference Between setRootName and setName?](#what-is-the-difference-between-setrootname-and-setname) * [How Do I Run Multiple Applications on One Host?](#how-do-i-run-multiple-applications-on-one-host) * [What Operating Systems Does AppSignal Support?](#what-operating-systems-does-appsignal-support) * [How Do I Debug an Issue with the AppSignal Integration?](#how-do-i-debug-an-issue-with-the-appsignal-integration) * [Does AppSignal Support Windows?](#does-appsignal-support-windows) * [Why Does Installing the AppSignal Ruby Gem Fail With a JSON::Fragment Error?](#why-does-installing-the-appsignal-ruby-gem-fail-with-a-jsonfragment-error) * [How Do I Configure AppSignal in a Hanami Application?](#how-do-i-configure-appsignal-in-a-hanami-application) * [User Account](#user-account) * [How Do I Enable Two-Factor Authentication (2FA) For the AppSignal App?](#how-do-i-enable-two-factor-authentication-2fa-for-the-appsignal-app) * [Why Aren't My Two-Factor Authentication (2FA) Codes Working?](#why-aren’t-my-two-factor-authentication-2fa-codes-working) * [What IP Addresses does AppSignal Use?](#what-ip-addresses-does-appsignal-use) * [Errors & Performance](#errors--performance) * [Why Is My Performance Issue Always Marked as Closed?](#why-is-my-performance-issue-always-marked-as-closed) * [How Do I See Error Counts Per Namespace?](#how-do-i-see-error-counts-per-namespace) * [How Long Is Uptime Monitoring Data Retained?](#how-long-is-uptime-monitoring-data-retained) ## Getting Started ### I Need Help Getting Started. Where Do I Begin? If you're new to AppSignal or want to know more about configuring AppSignal features, please [read our guides](/guides/) ## AppSignal Libraries ### What Programming Languages Does AppSignal Support? AppSignal supports the [Node.js](https://nodejs.dev), [Ruby](https://www.ruby-lang.org/en/) and [Elixir](https://elixir-lang.org/) programming languages. We also have [JavaScript packages](/front-end) for catching client-side errors in supported browsers. ### Filtering Data #### How Do I Ignore Actions in My Application? You can [Ignore Actions](/guides/filter-data/ignore-actions) to stop recording data for specific actions, requests, background jobs, etc. #### How Do I Ignore Errors in My Application? You can [Ignore Errors](/guides/filter-data/ignore-errors) (based on their name) to prevent AppSignal from reporting and alerting you to them. #### How do I Filter Data That's Sent to AppSignal? To learn how to filter the data that is sent to AppSignal, read one of the following guides: * [Filter Request Parameters and Background Job Arguments](/guides/filter-data/filter-parameters) * [Filter Session Data for HTTP Requests](/guides/filter-data/filter-session-data) * [Filter HTTP Request Headers](/guides/filter-data/filter-headers) ### How do I Add Additional Instrumentation to My Application? Additional instrumentation can be added to your application to give you more insights into how your application is performing by measuring the duration of separate events. Lean how in the documentation for our [Ruby Gem](/ruby/instrumentation/instrumentation) and [Elixir Package](/elixir/instrumentation/instrumentation). ### What Is the Difference Between setRootName and setName? `setName` and `setRootName` both rename spans, but at different levels. `setName` sets the name of an individual span as it appears in the performance sample timeline, while `setRootName` sets the name of the root transaction β€” what you see in the performance overview and transaction list. A good pattern is to call `setRootName` once on your outermost handler (for example, `` `${request.method} ${pattern}` `` to produce a title like `GET /users/:id`), and use `setName` together with `setCategory` on inner spans such as middleware, loaders, and actions, so they appear as clearly labeled events in the timeline breakdown. For more on naming and adding spans, see the [Node.js instrumentation guide](/nodejs/3.x/instrumentation/instrumentation). ### How Do I Run Multiple Applications on One Host? By default AppSignal is configured to assume one application runs on one host. If you run more than one application on a host, some unexpected behavior may occur, such as data being reported for a different application. To configure AppSignal for multiple applications on one host the AppSignal Working Directory needs to be configured. Read more about how to configure the working directory in our [Guide to Running Multiple Application on One Host](/guides/application/multiple-applications-on-one-host) ### What Operating Systems Does AppSignal Support? Please read our [Operating Systems](/support/operating-systems) page for the full list of supported Operating Systems and any required packages. ### How Do I Debug an Issue with the AppSignal Integration? Please read our [Debugging Guide](/support/debugging) for a complete guide to AppSignal Integration debugging issues. You can also check our [Known Issues](/support/known-issues) page for issues that may be present in your version of the AppSignal Integration. ### Does AppSignal Support Windows? AppSignal does not support Windows, and there are no plans to add Windows support. However, we do try to make the AppSignal libraries installable on Microsoft Windows without any errors or build issues. ### Why Does Installing the AppSignal Ruby Gem Fail With a JSON::Fragment Error? This error occurs when installing `appsignal` 4.x with Ruby 3.0 and earlier. The `json` gem bundled as a dependency in AppSignal 4.x introduced `JSON::Fragment`, a constant only available on Ruby 3.1 and later. On older Ruby versions the native extension build fails with: ``` uninitialized constant JSON::Fragment (NameError) ``` The recommended fix is to upgrade Ruby to 3.1 or later, which lets you use the current AppSignal 4.x release without restrictions. If you cannot upgrade Ruby right away, you can pin to AppSignal 3.x as a temporary workaround: add `gem "appsignal", "~> 3.0"` to your `Gemfile` and run `bundle update appsignal`. AppSignal 3.x works with Ruby 2.7 and Ruby 3.0, but does not receive new features from the 4.x line, so plan to upgrade Ruby when you can. ### How Do I Configure AppSignal in a Hanami Application? AppSignal does not auto-configure in Hanami the way it does in Rails. Use a Ruby configuration file (`config/appsignal.rb`) rather than the legacy YAML file (`config/appsignal.yml`) β€” the YAML format is deprecated and will be removed in the next major version of the gem. Create `config/appsignal.rb` with: ```ruby theme={null} Appsignal.configure do |config| config.activate_if_environment(:development, :staging, :production) config.name = "Your App Name" config.push_api_key = "your-key-here" end ``` Then make sure `config.ru` loads the integration after Hanami: ```ruby theme={null} require "appsignal" require "hanami/boot" Appsignal.load(:hanami) Appsignal.start run Hanami.app ``` If you have an existing `config/appsignal.yml`, remove it or add a `development` section with `active: true` β€” having both files causes conflicts. AppSignal does not start in the `development` environment by default; `activate_if_environment` opts it in explicitly. See the [Hanami integration docs](/ruby/integrations/hanami) for the full setup. ## User Account ### How Do I Enable Two-Factor Authentication (2FA) For the AppSignal App? Please refer to our [Two-Factor Authentication](/user-account/two-factor-authentication) page for more information on enabling 2FA. ### Why Aren't My Two-Factor Authentication (2FA) Codes Working? If your authenticator app's codes are rejected when you log in, the most common cause is clock drift on the device generating them. Two-factor authentication codes are time-based (TOTP), so that device's clock must be accurate β€” this often breaks after changing time zones. Enable automatic (network) date and time on the device, then try the newly generated code. If you still can't log in, use one of the five recovery codes you saved when you enabled 2FA to bypass two-factor authentication. See [Two-Factor Authentication](/user-account/two-factor-authentication) for more on recovery codes. ## What IP Addresses does AppSignal Use? Currently the AppSignal Push API uses the following IP addresses: <CodeGroup> ```text Text theme={null} 185.191.3.93 185.191.3.94 185.191.3.125 185.191.3.126 ``` </CodeGroup> Currently the AppSignal webhooks orginate from the following IP addresses: <CodeGroup> ```text Text theme={null} 185.191.3.107 185.191.3.72 185.191.3.116 185.191.3.84 ``` </CodeGroup> We don't recommend allowlisting specific IP addresses. They might change, and more may be added in the future, for instance, when we need to cycle our load balancers or quickly add servers. If you decide to allowlist our IP addresses, please [send our support team an email](mailto:support@appsignal.com), we'll do our best to notify you if there are upcoming changes. ## Errors & Performance ### Why Is My Performance Issue Always Marked as Closed? An issue's Open or Closed status is determined by its notification settings, not by whether the underlying problem is still happening. AppSignal marks an issue as Open when it sends a notification for it. Performance issues use the "Never Notify" setting by default, so no notification is sent β€” which is why they stay Closed. To have a performance issue open on new occurrences, change its notification setting, either per issue or by updating your organization-level default. See [Notification settings](/application/notification-settings) for how to configure this. ### How Do I See Error Counts Per Namespace? To see error counts per [namespace](/guides/namespaces), create a [Number chart](/metrics/dashboards) that uses the `transaction_exception_count` metric (AppSignal's count of errors recorded in an application), filtered by the `namespace` tag: 1. Open the application you want to measure, go to **Dashboards**, and add a new chart. 2. Select the **Number** tab. 3. Set the metric to `transaction_exception_count`. 4. Add the **namespace** tag and enter the namespace name (for example, `web` or `background`). 5. Set the aggregation type to **Total value**. 6. Create the chart. The chart shows the total error count for that namespace over the time frame you select when viewing it. AppSignal stores error data separately per application, so there is no single total across all applications β€” create one chart per namespace per application, and add the counts together yourself if you need an overall figure. ### How Long Is Uptime Monitoring Data Retained? Uptime monitoring stores minutely metrics for 30 days and hourly metrics for 5 years. To view daily uptime trends over a longer period β€” for example, a full year β€” use the date picker in the [uptime monitoring](/uptime-monitoring/setup) view to select a custom date range. # AppSignal for JavaScript Source: https://docs.appsignal.com/front-end AppSignal has amazing support for catching errors from front-end JavaScript applications and sending them to AppSignal. An `npm` library for catching JavaScript errors is available for that. <Warning> **NOTE:** Uncaught exceptions are **not** captured by default. [Read this section to find out why](/front-end/error-handling#uncaught-exceptions). You can enable this functionality by enabling the [`plugin-window-events`](/front-end/plugins/plugin-window-events) plugin. </Warning> ## Supported browsers This package can be used in any ECMAScript 5 compatible browser. We aim for compatibility down to Internet Explorer 9 [(roughly 0.22% of all browsers used today)](https://www.w3counter.com/globalstats.php). All browsers older than this can only supported on a β€œbest effort” basis, and full functionality cannot be guaranteed. When developing, don’t forget to check browser support on [Can I Use?](https://caniuse.com/) and the [ES6 Compatibility Table](https://compat-table.github.io/compat-table/es6/), and provide the appropriate polyfills or fallbacks. **In a small percentage of browsers, a `Promise` polyfill may be required to use this library.** ## Other supported environments `@appsignal/javascript` is more than just a front-end library! It's also designed to work in a variety of other JavaScript runtimes and use-cases where the `@appsignal/nodejs` library may not be a viable choice. `@appsignal/javascript` supports: # Breadcrumbs Source: https://docs.appsignal.com/front-end/breadcrumbs When debugging an issue in a UI, it can be useful to know what events occurred in the build up to the error being thrown. Breadcrumbs are a time-ordered list of events in your application, that is filled as a user traverses your application, and is sent along with a `Span` whenever an error is caught by the library. This allows you to gather information that is useful for reproducing tricky-to-debug errors by re-tracing a user's path through your application. <img alt="Breadcrumbs" /> ## Usage By default, no breadcrumbs are tracked, but it's really easy to track your own. Alternatively, you can use one of our [breadcrumb plugins](#plugins) to automatically collect some types of breadcrumbs. Wherever an interesting event, operation or state change occurs in your app, you can leave a breadcrumb like so: <CodeGroup> ```js JavaScript theme={null} import Appsignal from "@appsignal/javascript"; const appsignal = new Appsignal({ key: "YOUR FRONTEND API KEY", }); appsignal.addBreadcrumb({ category: "", // e.g. "UI", "Network", "Navigation", "Console" action: "", // e.g "The user clicked a button", "HTTP 500 from http://blablabla.com" metadata: {}, // key/value metadata in <String, String> format }); ``` </CodeGroup> When an error is thrown and caught by the AppSignal library, or a `Span` is passed to `appsignal.send()`, the current list of breadcrumbs is added to the current `Span` and sent to the server. The list of breadcrumbs is then emptied. ## Breadcrumb Options | Option | Type | Description | | -------- | ------------------------ | ------------------------------------------------------------- | | category | String | Category to label the event under | | action | String | Contextual information related to the event | | message | String | (optional) A log message or other string to send to AppSignal | | metadata | `Object<String, String>` | (optional) An object of metadata related to the event | ## Plugins There are a number of plugins available to enable automatic collection of breadcrumbs, and more will be added as time goes on: * [`@appsignal/plugin-breadcrumbs-console`](https://github.com/appsignal/appsignal-javascript/tree/develop/packages/plugin-breadcrumbs-console) * [`@appsignal/plugin-breadcrumbs-network`](https://github.com/appsignal/appsignal-javascript/tree/develop/packages/plugin-breadcrumbs-network) Have a good idea for a breadcrumbs plugin? Get in touch with us or [leave an issue on GitHub](https://github.com/appsignal/appsignal-javascript/issues)! # AppSignal for JavaScript configuration Source: https://docs.appsignal.com/front-end/configuration ## Setting up AppSignal To configure AppSignal for front-end JavaScript, we recommend creating an `appsignal.js` file with the AppSignal config in your project's root or `src` directory. Then require or import the configuration file from the app's code before any other packages are required or imported. In the example below, there is an `appsignal.js` file in the root of the applications directory. On line 8 we've added the `namespace` config option. <CodeGroup> ```javascript JavaScript theme={null} // For ES Module via npm/yarn, or with import maps import Appsignal from "@appsignal/javascript"; // For CommonJS module via npm/yarn const Appsignal = require("@appsignal/javascript").default; // With the JSPM.dev CDN import Appsignal from "https://jspm.dev/@appsignal/javascript"; const appsignal = new Appsignal({ key: "<YOUR FRONTEND API KEY>", }); module.exports = { appsignal }; ``` </CodeGroup> ## Customize the configuration You can customize the error reporting from your application with the [Front-end configuration options](/front-end/configuration/options). Here's an example of how the [namespace option](/front-end/configuration/options#namespace) is customized. <CodeGroup> ```diff Example namespace option theme={null} const appsignal = new Appsignal({ key: "<YOUR FRONTEND API KEY>", + namespace: "frontend", // Configure the AppSignal namespace for front-end errors in this app }); ``` </CodeGroup> ## Require the AppSignal configuration Once you're done with your application's config, require the `appsignal.js` file at the very top of your application's main file, like in the example below: <CodeGroup> ```javascript JavaScript theme={null} // Place this at the top // Import the file created in the previous step const { appsignal } = require("./appsignal"); // Update to the location used in the previous step // Place your app code below this ``` </CodeGroup> After your application loads the AppSignal JavaScript library, make sure to follow all the [steps in the installation guide](/front-end/installation), adding [integrations](/front-end/integrations), adding [plugins](/front-end/plugins), and customize your [configuration](/front-end/configuration/options). # AppSignal for JavaScript configuration options Source: https://docs.appsignal.com/front-end/configuration/options The following list includes all configuration options with the name of the environment variable and the name of the key in the configuration file. For more information on how to configure AppSignal with a configuration file, see our [Configuration](/front-end/configuration) topic. ## `key` * **Type:** `string` <Tip> This configuration option is **required** to send data to AppSignal. If this configuration option is not set, AppSignal for JavaScript will run in development mode, and no data will be sent to AppSignal. </Tip> The front-end error monitoring API key for your application. You can find this API key under "Front-end error monitoring" in the ["Push & Deploy"](https://appsignal.com/redirect-to/app?to=api_keys) section of your application's settings. This is **not** the same as the organization-level or application-level API key, which is used for monitoring in our back-end integrations. ## `namespace` * **Type:** `string` * **Default value:** `"frontend"` The default namespace to use to report errors to AppSignal. Read more in our [namespaces guide](/guides/namespaces). ## `revision` * **Type:** `string` Set the app revision for the currently running version of your app. This is used to create deploy markers and tag all incoming data as belonging to a specific deploy. Read more in our [deploy markers guide](/application/markers/deploy-markers). ## `ignoreErrors` * **Type:** `RegExp[]` An array of regular expressions to check against the `message` property of any error reported to AppSignal. If any of the regular expressions matches, the error is ignored. Read more in our [ignoring errors guide](/guides/filter-data/ignore-actions). ## `matchBacktracePaths` <Compatibility /> * **Type:** `RegExp[]` <Warning> This configuration option is useful when developing applications for desktop and mobile environments, or when deploying the same application environment to multiple domains. **Most applications will not need to use this configuration option.** **Using this configuration option will break [public sourcemap detection](/front-end/sourcemaps#public-sourcemaps).** To use this configuration option with a sourcemapped codebase, you must upload private sourcemaps for your application. This configuration option is **experimental** and may change in future versions. </Warning> An array of regular expressions with one or more match groups. These regular expressions will be checked against the backtrace line paths of errors reported to AppSignal. If any of the regular expressions matches with one or more non-empty match groups, the path in the backtrace line is replaced with the result of concatenating the match groups. This is useful when the path at which your application is deployed is not known ahead of time. For example, the path to an Electron application may be different on each user's machine. You can match for the part of that path that is known to represent your application. For example, if your application's source code is located at a path like the following, where `${USERNAME}` changes for each user: <CodeGroup> ```sh Shell theme={null} /Users/${USERNAME}/Applications/MyApp.app/Contents/Resources/bundle/app.js` ``` </CodeGroup> Then you can use this configuration option as follows: <CodeGroup> ```javascript JavaScript theme={null} const appsignal = new Appsignal({ // ... other configuration options ... matchBacktracePaths: [new RegExp("MyApp.app/Contents/Resources/(.*)")], }); ``` </CodeGroup> When an error is reported, the backtrace line paths will be replaced with the result of the match group, which in this example will be `bundle/app.js`. This ensures that errors reported to AppSignal are grouped correctly when using backtrace line grouping, and allows for [private sourcemaps](/api/sourcemaps) to be uploaded for the cleaned path. # Frontend error catching Source: https://docs.appsignal.com/front-end/error-handling To report an error to AppSignal, catch the error and pass it to the `sendError` helper function. If you're using TypeScript, to use the `sendError` helper function, the argument must be an instance of `Error` or `ErrorEvent`. That's because in TypeScript, caught variables are of type `unknown` by default in strict mode since version 4.4. <CodeGroup> ```javascript JavaScript theme={null} try { // do something that might throw an error } catch (error) { if (error instanceof Error || error instanceof ErrorEvent) { appsignal.sendError(error) // handle the error } } // You can catch errors asynchronously by listening to Promises... asyncActionThatReturnsAPromise().catch(error => appsignal.sendError(error)) // ...or by using async/await async function() { try { const result = await asyncActionThatReturnsAPromise() } catch (error) { if (error instanceof Error || error instanceof ErrorEvent) { appsignal.sendError(error) // handle the error } } } // ...or in an event handler or callback function events.on("event", (err) => { appsignal.sendError(err) }) ``` </CodeGroup> ## Adding metadata to errors To add additional metadata to errors sent with `sendError`, use the callback function argument. This callback receives the current Span for the error as an argument and allows it to be modified before being sent to the AppSignal servers. See the [Span API page][span api] for more information about all the data that can be set on a Span. <CodeGroup> ```javascript JavaScript theme={null} try { // do something that might throw an error } catch (error) { appsignal.sendError(error, (span) => { span.setAction("MyCustomAction"); span.setNamespace("custom_namespace"); span.setTags({ tag1: "value 1", tag2: "value 2" }); }); // handle the error } ``` </CodeGroup> ## Uncaught exceptions Uncaught exceptions are **not** captured by default. We made the decision to not include this functionality as part of the core library due to the high amount of noise from browser extensions, ad blockers etc. that generally makes libraries such as this less effective. We recommend using a relevant [integration](/front-end/integrations/) as a better way to handle exceptions, or, if you *would* prefer capture uncaught exceptions, you can do so by using the [`@appsignal/plugin-window-events`](/front-end/plugins/plugin-window-events) package alongside this one. ## Wrapping a block of code The library provides a convenience method for wrapping a block of code and sending any error thrown within it directly to AppSignal. This is the `appsignal.wrap()` method, an async function that returns a `Promise`. A function should be passed as an argument containing the code you'd like to wrap. <CodeGroup> ```javascript JavaScript theme={null} try { await appsignal.wrap(() => { // catch any error from sync or async code here }); } catch (e) { // do something else with the error here, the // error has already been sent to AppSignal } // Alternative usage appsignal .wrap(() => { // catch any error from sync or async code here }) .catch((e) => { // do something else with the error here, the // error has already been sent to AppSignal }); ``` </CodeGroup> If an error is thrown anywhere in this function, we return a rejected promise with the `Error` passed as an argument to the `catch` handler. ### Adding metadata to wrapped errors To add additional metadata to errors captured and sent with `wrap`, use the callback function argument. This callback receives the current Span for the error as an argument and allows it to be modified before being sent to the AppSignal servers. See the [Span API page][span api] for more information about all the data that can be set on a Span. <CodeGroup> ```javascript JavaScript theme={null} appsignal.wrap( () => { throw new Error("Test error"); }, (span) => { span.setAction("MyCustomAction"); span.setNamespace("custom_namespace"); span.setTags({ tag1: "value 1", tag2: "value 2" }); }, ); ``` </CodeGroup> ## GraphQL errors If you're using the `urql` GraphQL client, please see the [`@appsignal/urql` documentation](/front-end/integrations/urql) for instructions on how to set up error reporting from GraphQL. [span api]: /front-end/span.html # Hooks Source: https://docs.appsignal.com/front-end/hooks In the life cycle of a `Span`, we provide a number of opportunities to update or modify its internal state. Hooks are the mechanism for this. Using specifically formed functions, we are able to augment any outgoing `Span` with additional information before it is sent to the Push API. Both types of hooks are an array of composed functions that are applied from right to left. In other words, the hooks that are added last are always the first to be applied. When a `Span` is passed to `appsignal.send()`, or an `Error` is passed to `appsignal.sendError()`, hooks are applied to the `Span` in the following order: * Decorators * Optional `tags` or `namespace` arguments to `appsignal.send()` * Overrides Hooks are generally applied in a plugin. <Tip> When an `Error` is passed to `appsignal.sendError()`, an internal `Span` object is created, meaning that Hooks can still be applied to it as normal. </Tip> ## Decorators It may be necessary to add additional context to a `Span` at the global level, so that all requests by default include that information. Decorators can be used to do this. ## Overrides Overrides are the last possible opportunity to update data in a `Span` before it is sent to the Push API. For example, you may choose to scrub any user data from `Span`s in an override. ## Writing your own Hook Hooks are, essentially, functions that take a `Span` as a single argument, and then return the same `Span`. During the execution of the function, modifications can be made to the `Span`, but we suggest that no other side-effects are introduced. Here's an example of how you can add a Hook to the `Appsignal` object: <CodeGroup> ```js JavaScript theme={null} appsignal.addDecorator((span) => { return span.setTags({ customTag: "value" }); }); appsignal.addOverride((span) => { // scrub e-mail addresses const { tags } = span.serialize(); return span.setTags({ text: tags.text.replace(/^[^\s@]+@[^\s@]+\.[^\s@]+$/, "[SCRUBBED]"), }); }); ``` </CodeGroup> Plugins can add decorators and overrides, too. If you're looking to create a re-usable hook, that can be packaged in an `npm` module, for instance, we recommend utilizing [the plugin interface](/front-end/plugins/) to register it. # Installing AppSignal for JavaScript Source: https://docs.appsignal.com/front-end/installation Please follow the [installation guide](/guides/new-application) first, when adding a new application to AppSignal. ## Creating a Push API Key Before you begin, you'll need to find your Push API key on the ["Push and deploy" section](https://appsignal.com/redirect-to/app?to=info) of your App settings page. You'll be able to find your API key under the "Front-end error monitoring". Once you have your key, follow the instructions under the [Installation](#installation) section to use it in your application. ## Installation ### With npm or yarn First, add the `@appsignal/javascript` package to your `package.json`. Then, run `yarn install`/`npm install`. You'll also need a Front-end error monitoring key from the ["Push and deploy" section](https://appsignal.com/redirect-to/app?to=info) of your App settings page. You can also add these packages to your `package.json` on the command line: <CodeGroup> ```bash Bash theme={null} yarn add @appsignal/javascript npm install @appsignal/javascript ``` </CodeGroup> ### With JSPM.dev <Warning> It is not recommended to use the JSPM.dev CDN in production. For a production-ready setup without a build step, we recommend using [JSPM.io import maps](#with-jspmio-import-maps). </Warning> Thanks to the JSPM CDN, it is possible to use the AppSignal for JavaScript integration without a front-end asset build step. Your application can import packages directly from the CDN: <CodeGroup> ```js JavaScript theme={null} import Appsignal from "https://jspm.dev/@appsignal/javascript"; ``` </CodeGroup> ### With JSPM.io import maps Using the [JSPM.io import map generator](https://generator.jspm.io/), you can generate an import map for your application's dependencies. Add `@appsignal/javascript` to the dependencies list, then add the generated import map and ES module shims to your application's code. ### With `rails-importmap` Use the following command to add these packages to your Rails application's import maps: <CodeGroup> ```sh Shell theme={null} ./bin/importmap pin @appsignal/javascript ``` </CodeGroup> ## Usage Create an `appsignal.js` file to require and configure AppSignal. From this file, we export the instance of the `Appsignal` object that we will use from our application. For more information about the configuration, see our [configuration section](/front-end/configuration). <CodeGroup> ```javascript JavaScript theme={null} // For ES Module via npm/yarn, or with import maps import Appsignal from "@appsignal/javascript"; // For CommonJS module via npm/yarn const Appsignal = require("@appsignal/javascript").default; // With the JSPM.dev CDN import Appsignal from "https://jspm.dev/@appsignal/javascript"; export const appsignal = new Appsignal({ key: "YOUR FRONTEND API KEY", }); ``` </CodeGroup> You can then import and use the `Appsignal` object in your app: <CodeGroup> ```javascript JavaScript theme={null} // Place this at the top // Import the file created in the previous step import { appsignal } from "./appsignal"; // Place your app code below this ``` </CodeGroup> <Warning> **NOTE:** If you are running a CDN in front of your assets, you'll need to make [two changes](/front-end/troubleshooting) for error reporting to be able to send errors to our API endpoint. Read more about the [required changes](/front-end/troubleshooting). If you use Content Security Policy, make sure to add the correct headers as [described here](/front-end/troubleshooting#content-security-policy-csp). </Warning> ## Add integrations Your application may be using a framework or library that AppSignal supports. Please check out the [integrations](/front-end/integrations) section for any library our application uses and follow the instructions to add instrumentation for those libraries. [Add integrations to your application](/front-end/integrations). ## Add plugins AppSignal also offers some plugins for JavaScript functionality in the browser. Please check out the [plugins](/front-end/plugins) section for any additional instrumentation you would like to add to your application. [Add plugins to your application](/front-end/plugins). ## Custom error reporting Not using a framework or library but would like to report JavaScript errors manually? Use our [Span API](/front-end/span) to create spans on which to report errors, add tags and more metadata. Then read our [error handling guide](/front-end/error-handling) on how to report errors to AppSignal. *** <Note> πŸ“– Continue with our [installation guide](/guides/new-application). </Note> ## Uninstall Uninstall AppSignal from your app by following the steps below. When these steps are completed your app will no longer send data to the AppSignal servers. 1. In the `package.json` of your app, delete all lines referencing an `appsignal` package: `"*appsignal/*": "*"`. 2. Run `npm install` or `yarn install` to update your `package.lock`/`yarn.lock` with the removed packages state. * Alternatively, run `npm uninstall @appsignal/<package name>` or `yarn remove @appsignal/<package name>` to uninstall an AppSignal package. 3. Remove any AppSignal [configuration](/front-end/configuration/) from your app. 4. Commit, deploy and restart your app. * This will make sure the AppSignal servers won't continue to receive data from your app. 5. Finally, [remove the app](/guides/application/deleting-applications) on AppSignal.com. <Note> πŸ“– Continue with our [uninstall guide](/guides/application/deleting-applications). </Note> # AppSignal for JavaScript integrations Source: https://docs.appsignal.com/front-end/integrations ## Integrations An integration is a module that can consume the `Appsignal` object to catch errors from popular libraries or frameworks. These integrations may come in a variety of different forms, and we aim to generally provide APIs that are consistent, and feel idiomatic to use, with the libraries and/or frameworks that you’re using. These currently include: * [React - `@appsignal/react`](/front-end/integrations/react) (works with React Native and Expo) * [Vue - `@appsignal/vue`](/front-end/integrations/vue) * [Angular - `@appsignal/angular`](/front-end/integrations/angular) * [Ember - `@appsignal/ember`](/front-end/integrations/ember) * [Preact - `@appsignal/preact`](/front-end/integrations/preact) * [Stimulus - `@appsignal/stimulus`](/front-end/integrations/stimulus) # @appsignal/angular Source: https://docs.appsignal.com/front-end/integrations/angular ## Installation ### With npm or yarn Add the `@appsignal/angular` and `@appsignal/javascript` packages to your `package.json`. Then, run `yarn install`/`npm install`. You can also add these packages to your `package.json` on the command line: <CodeGroup> ```bash Bash theme={null} yarn add @appsignal/javascript @appsignal/angular npm install @appsignal/javascript @appsignal/angular ``` </CodeGroup> ### With JSPM.io import maps Using the [JSPM.io import map generator](https://generator.jspm.io/), you can generate an import map for your application's dependencies. Add `@appsignal/javascript` and `@appsignal/angular` to the dependencies list, then add the generated import map and ES module shims to your application's code. ### With `rails-importmap` Use the following command to add these packages to your Rails application's import maps: <CodeGroup> ```sh Shell theme={null} ./bin/importmap pin @appsignal/javascript @appsignal/angular ``` </CodeGroup> ## Usage ### `AppsignalErrorHandler` The default Angular integration is a class that extends the `ErrorHandler` class provided by `@angular/core`. In a new app created using `@angular/cli`, your `app.module.ts` file might include something like this: <CodeGroup> ```js JavaScript theme={null} import { ErrorHandler, NgModule } from "@angular/core"; import { appsignal } from "./appsignal"; import { createErrorHandlerFactory } from "@appsignal/angular"; @NgModule({ // other properties providers: [ { provide: ErrorHandler, useFactory: createErrorHandlerFactory(appsignal), }, ], // other properties }) export class AppModule {} ``` </CodeGroup> # @appsignal/ember Source: https://docs.appsignal.com/front-end/integrations/ember ## Installation Add the `@appsignal/ember` and `@appsignal/javascript` packages to your `package.json`. Then, run `yarn install`/`npm install`. You can also add these packages to your `package.json` on the command line: <CodeGroup> ```bash Bash theme={null} yarn add @appsignal/javascript @appsignal/ember npm install @appsignal/javascript @appsignal/ember ``` </CodeGroup> Starting with Ember 4, projects created with `ember new` include `ember-auto-import` out of the box. If your project does not, you will need to add some kind of method for loading `npm` packages into your application. We recommend using [`ember-auto-import`](https://github.com/ef4/ember-auto-import), which you can install using `ember-cli`: ```bash Bash theme={null} ember install ember-auto-import ``` [A number of other methods and custom configurations are available](https://guides.emberjs.com/release/addons-and-dependencies/) for importing this library in a way that suits your app. ## Usage ### `Ember.onerror`/`Ember.RSVP.on("error")` The default Ember integration is a function that binds to the `Ember.onerror` and `Ember.RSVP.on("error")` handlers. In a new app created using `ember-cli`, your `app.js` file might include something like this: <CodeGroup> ```js JavaScript theme={null} import { appsignal } from "./appsignal"; import Ember from "ember"; import { installErrorHandler } from "@appsignal/ember"; installErrorHandler(appsignal, Ember); ``` </CodeGroup> # @appsignal/preact Source: https://docs.appsignal.com/front-end/integrations/preact <VersionRequirements /> ## Installation ### With npm or yarn Add the `@appsignal/preact` and `@appsignal/javascript` packages to your `package.json`. Then, run `npm install`/`yarn install`. You can also add these packages to your `package.json` on the command line: <CodeGroup> ```sh Shell theme={null} yarn add @appsignal/javascript @appsignal/preact npm install @appsignal/javascript @appsignal/preact ``` </CodeGroup> ### With JSPM.io import maps Using the [JSPM.io import map generator](https://generator.jspm.io/), you can generate an import map for your application's dependencies. Add `@appsignal/javascript` and `@appsignal/preact` to the dependencies list in the generator, then add the generated import map and ES module shims to your application's code. ### With `rails-importmap` Use the following command to add these packages to your Rails application's import maps: <CodeGroup> ```sh Shell theme={null} ./bin/importmap pin @appsignal/javascript @appsignal/preact ``` </CodeGroup> ## Usage ### Error Boundary If you are using Preact v10.0.0 or higher, you can use the `ErrorBoundary` component to catch errors from anywhere in the child component tree. <CodeGroup> ```jsx JavaScript theme={null} import { Component } from "preact"; import { appsignal } from "./appsignal"; import { ErrorBoundary } from "@appsignal/preact"; const FallbackComponent = () => ( <div>Uh oh! There was an error :(</div> ); export default class App extends Component { render() { return ( <ErrorBoundary instance={appsignal} tags={{ tag: "value" }} {/* Optional */} fallback={(error) => <FallbackComponent />} {/* Optional */} > { /** Child components here **/} </ErrorBoundary> ) } } ``` </CodeGroup> # @appsignal/react Source: https://docs.appsignal.com/front-end/integrations/react ## Installation ### With npm or yarn Add the `@appsignal/react` and `@appsignal/javascript` packages to your `package.json`. Then, run `npm install`/`yarn install`. You can also add these packages to your `package.json` on the command line: <CodeGroup> ```sh Shell theme={null} yarn add @appsignal/javascript @appsignal/react npm install @appsignal/javascript @appsignal/react ``` </CodeGroup> <Tip> You can also use the React integration with React Native and Expo. </Tip> ### With JSPM.io import maps Using the [JSPM.io import map generator](https://generator.jspm.io/), you can generate an import map for your application's dependencies. Add `@appsignal/javascript` and `@appsignal/react` to the dependencies list in the generator, then add the generated import map and ES module shims to your application's code. ### With `rails-importmap` Use the following command to add these packages to your Rails application's import maps: <CodeGroup> ```sh Shell theme={null} ./bin/importmap pin @appsignal/javascript @appsignal/react ``` </CodeGroup> ## Usage You must pass the AppSignal client instance as the `instance` prop. In addition, the following props can optionally be passed to both the `ErrorBoundary` and `LegacyBoundary` components: | Prop name | Description | | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `action` | The action name for which to show errors reported by this boundary. We recommend using the name of the component. | | `tags` | An object containing the tags to set for errors reported by this boundary. | | `fallback` | A function that optionally takes the error as an argument, and returns a fallback component to use when rendering fails. | | `override` | A function that takes the error span, and optionally the error itself, as arguments, and returns a modified span. Only called when an error is reported. Use it to [set tags, params or breadcrumbs](/front-end/span#updating-a-span) on the error sample. | When using `tags`, `fallback` or `override`, use `useMemo` (or `useCallback` for `fallback` and `override`) to memoize the values. This will prevent unnecessary re-renders. ### Error Boundary If you are using React v16 or higher, you can use the `ErrorBoundary` component to catch errors from anywhere in the child component tree. <CodeGroup> ```jsx JavaScript theme={null} import React from "react"; import ReactDOM from "react-dom"; import { appsignal } from "./appsignal"; import { ErrorBoundary } from "@appsignal/react"; const FallbackComponent = () => ( <div>Uh oh! There was an error :(</div> ); const App = () => ( const tags = useMemo(() => ({ tag: "value" }), []); const fallback = useCallback((error) => <FallbackComponent />, []); const override = useCallback((span, error) => { span.setParams({ customParams: "123" }); return span }, []); <ErrorBoundary instance={appsignal} action="App" tags={tags} override={override} fallback={fallback} > { /* Child components here */ } </ErrorBoundary> ); ReactDOM.render(<App />, document.getElementById("root")); ``` </CodeGroup> ### Legacy Boundary <Warning> The API that this component uses is unstable at this point in React's development. We offer this component as a means to support those running React v15, but do not guarantee its reliablity. You are encouraged to use the `ErrorBoundary` whenever possible. </Warning> The `LegacyBoundary` works in almost exactly the same way as the `ErrorBoundary`: <CodeGroup> ```jsx JavaScript theme={null} import React from "react"; import ReactDOM from "react-dom"; import { appsignal } from "./appsignal"; import { LegacyBoundary } from "@appsignal/react"; const FallbackComponent = () => ( <div>Uh oh! There was an error :(</div> ); const App = () => ( const tags = useMemo(() => ({ tag: "value" }), []); const fallback = useCallback((error) => <FallbackComponent />, []); const override = useCallback((span, error) => { span.setParams({ customParams: "123" }); return span }, []); <LegacyBoundary instance={appsignal} action="App" tags={tags} fallback={fallback} override={override} > { /* Child components here */ } </LegacyBoundary> ); ReactDOM.render(<App />, document.getElementById("root")); ``` </CodeGroup> # @appsignal/stimulus Source: https://docs.appsignal.com/front-end/integrations/stimulus ## Installation ### With npm or yarn Add the `@appsignal/stimulus` and `@appsignal/javascript` packages to your `package.json`. Then, run `yarn install`/`npm install`. You can also add these packages to your `package.json` on the command line: <CodeGroup> ```bash Bash theme={null} yarn add @appsignal/javascript @appsignal/stimulus npm install @appsignal/javascript @appsignal/stimulus ``` </CodeGroup> ### With JSPM.io import maps Using the [JSPM.io import map generator](https://generator.jspm.io/), you can generate an import map for your application's dependencies. Add `@appsignal/javascript` and `@appsignal/stimulus` to the dependencies list in the generator, then add the generated import map and ES module shims to your application's code. ### With `rails-importmap` Use the following command to add these packages to your Rails application's import maps: <CodeGroup> ```sh Shell theme={null} ./bin/importmap pin @appsignal/javascript @appsignal/stimulus ``` </CodeGroup> ## Usage ### `Application.handleError` The default Stimulus integration is a function that binds to the `Application.handleError` property. In a new app created using `rails new $APP_NAME --webpack=stimulus`, for example, your `javascript/controllers/index.js` file would look something like this: <CodeGroup> ```js JavaScript theme={null} import { Application } from "stimulus"; import { definitionsFromContext } from "stimulus/webpack-helpers"; import { appsignal } from "./appsignal"; import { installErrorHandler } from "@appsignal/stimulus"; const application = Application.start(); installErrorHandler(appsignal, application); const context = require.context("controllers", true, /_controller\.js$/); application.load(definitionsFromContext(context)); ``` </CodeGroup> # @appsignal/urql Source: https://docs.appsignal.com/front-end/integrations/urql [`urql`](https://urql.dev/) is a GraphQL client for JavaScript applications. The `@appsignal/urql` package provides a [custom exchange](https://urql.dev/docs/architecture/#the-exchanges), which, once added to your `urql` client, automatically intercepts all GraphQL errors and reports them to AppSignal. ## Installation ### `npm` or `yarn` Add the `@appsignal/urql` and `@appsignal/javascript` packages to your `package.json`. Then, run `npm install`/`yarn install`. You can also add these packages to your `package.json` on the command line: <CodeGroup> ```sh Shell theme={null} yarn add @appsignal/javascript @appsignal/urql npm install @appsignal/javascript @appsignal/urql ``` </CodeGroup> ### JSPM.io import maps Using the [JSPM.io import map generator](https://generator.jspm.io/), you can generate an import map for your application's dependencies. Add `@appsignal/javascript` and `@appsignal/urql` to the dependencies list in the generator, then add the generated import map and ES module shims to your application's code. ### `rails-importmap` Use the following command to add these packages to your Rails application's import maps: <CodeGroup> ```sh Shell theme={null} ./bin/importmap pin @appsignal/javascript @appsignal/urql ``` </CodeGroup> ## Usage ### Adding exchange to the client The `@appsignal/urql` package provides a custom urql exchange that automatically reports GraphQL errors to AppSignal. This exchange intercepts all query and mutation results and reports any errors without requiring changes to individual `useQuery` calls. <CodeGroup> ```typescript TypeScript theme={null} import { createClient, fetchExchange } from "urql"; import Appsignal from "@appsignal/javascript"; import { createAppsignalExchange } from "@appsignal/urql"; const appsignal = new Appsignal({ key: "YOUR FRONTEND API KEY", }); const client = createClient({ url: "https://api.example.com/graphql", exchanges: [createAppsignalExchange(appsignal), fetchExchange], }); ``` </CodeGroup> The exchange will automatically: * Report all GraphQL errors to AppSignal * Include the GraphQL query body as a parameter (visible in AppSignal's error details) * Include the endpoint URL as a tag * Include operation name and type as tags (when available) ## Error Details When a GraphQL error occurs, AppSignal will receive: * **Error message**: A concatenation of all GraphQL error messages * **Tags**: * `endpoint`: The GraphQL endpoint URL * `operationName`: The name of the GraphQL operation (if specified) * `operationType`: The type of operation (query, mutation, subscription) * **Parameters**: * `query`: The full GraphQL query body This provides complete context for debugging GraphQL errors in your application. # @appsignal/vue Source: https://docs.appsignal.com/front-end/integrations/vue ## Installation ### With npm or yarn Add the `@appsignal/vue` and `@appsignal/javascript` packages to your `package.json`. Then, run `npm install`/`yarn install`. You can also add these packages to your `package.json` on the command line: <CodeGroup> ```sh Shell theme={null} yarn add @appsignal/javascript @appsignal/vue npm install @appsignal/javascript @appsignal/vue ``` </CodeGroup> ### With JSPM.io import maps Using the [JSPM.io import map generator](https://generator.jspm.io/), you can generate an import map for your application's dependencies. Add `@appsignal/javascript` and `@appsignal/vue` to the dependencies list in the generator, then add the generated import map and ES module shims to your application's code. ### With `rails-importmap` Use the following command to add these packages to your Rails application's import maps: <CodeGroup> ```sh Shell theme={null} ./bin/importmap pin @appsignal/javascript @appsignal/vue ``` </CodeGroup> ## Usage ### `Vue.config.errorHandler` The default Vue integration is a function that binds to Vue's global `errorHandler` hook. #### Vue v2 In a new Vue v2 app created using `@vue/cli`, your `main.js`/`.ts` file would look something like this: <CodeGroup> ```js JavaScript theme={null} import Vue from "vue"; import App from "./App.vue"; import router from "./router"; import store from "./store"; import { appsignal } from "./appsignal"; import { errorHandler } from "@appsignal/vue"; Vue.config.errorHandler = errorHandler(appsignal, Vue); new Vue({ router, store, render: (h) => h(App), }).$mount("#app"); ``` </CodeGroup> #### Vue v3 Version 3 of Vue includes a change to the way you'd use our Vue integration. Instead of attaching it to the global `Vue` object, you would use it like this instead: <CodeGroup> ```js JavaScript theme={null} import { createApp } from "vue"; import App from "./App.vue"; import { appsignal } from "./appsignal"; import { errorHandler } from "@appsignal/vue"; const app = createApp(App); app.config.errorHandler = errorHandler(appsignal, app); app.mount("#app"); ``` </CodeGroup> # AppSignal for JavaScript plugins Source: https://docs.appsignal.com/front-end/plugins ## Plugins The following plugins are available to add additional metadata to Front-end error reports. * [plugin-breadcrumbs-console](/front-end/plugins/plugin-breadcrumbs-console) * [plugin-breadcrumbs-network](/front-end/plugins/plugin-breadcrumbs-network) * [plugin-window-events](/front-end/plugins/plugin-window-events) * [plugin-path-decorator](/front-end/plugins/plugin-path-decorator) ## Loading plugins The `Appsignal` object can take one or many optional "plugins" that can extend the base functionality of the library e.g.Β for handling uncaught exceptions via `window.error` or `onunhandledpromiserejection`. <CodeGroup> ```javascript JavaScript theme={null} import { plugin } from `appsignal/plugin-${PLUGIN_NAME}` appsignal.use(plugin()) ``` </CodeGroup> # plugin-breadcrumbs-console Source: https://docs.appsignal.com/front-end/plugins/plugin-breadcrumbs-console The `@appsignal/javascript` plugin for automatically adding a breadcrumb on every call to any of the [supported `console` methods](https://github.com/appsignal/appsignal-javascript/blob/develop/packages/plugin-breadcrumbs-console/src/index.ts#L3), e.g. `console.log`, `console.warn`. ## Installation Add the `@appsignal/plugin-breadcrumbs-console` and `@appsignal/javascript` packages to your `package.json`. Then, run `yarn install`/`npm install`. You can also add these packages to your `package.json` on the command line: <CodeGroup> ```bash Bash theme={null} yarn add @appsignal/javascript @appsignal/plugin-breadcrumbs-console npm install @appsignal/javascript @appsignal/plugin-breadcrumbs-console ``` </CodeGroup> ## Usage <CodeGroup> ```js JavaScript theme={null} import Appsignal from "@appsignal/javascript"; import { plugin } from "@appsignal/plugin-breadcrumbs-console"; const appsignal = new Appsignal({ key: "YOUR FRONTEND API KEY", }); appsignal.use(plugin(options)); ``` </CodeGroup> ### `plugin` options The `plugin` currently receives no options. # plugin-breadcrumbs-network Source: https://docs.appsignal.com/front-end/plugins/plugin-breadcrumbs-network The `@appsignal/javascript` plugin for automatically adding a breadcrumb on every network request. Works with both `XMLHttpRequest` and `fetch`. ## Installation Add the `@appsignal/plugin-breadcrumbs-network` and `@appsignal/javascript` packages to your `package.json`. Then, run `yarn install`/`npm install`. You can also add these packages to your `package.json` on the command line: <CodeGroup> ```bash Bash theme={null} yarn add @appsignal/javascript @appsignal/plugin-breadcrumbs-network npm install @appsignal/javascript @appsignal/plugin-breadcrumbs-network ``` </CodeGroup> ## Usage <CodeGroup> ```js JavaScript theme={null} import Appsignal from "@appsignal/javascript"; import { plugin } from "@appsignal/plugin-breadcrumbs-network"; const appsignal = new Appsignal({ key: "YOUR FRONTEND API KEY", }); appsignal.use(plugin(options)); ``` </CodeGroup> ### `plugin` options The `plugin` can be initialized with the following options: | Param | Type | Description | | ------------ | ------- | --------------------------------------------------------------------------------------------------------------- | | xhrEnabled | Boolean | (optional) A boolean value representing whether the plugin should bind to `XMLHttpRequest`. Defaults to `true`. | | fetchEnabled | Boolean | (optional) A boolean value representing whether the plugin should bind to `fetch`. Defaults to `true`. | # plugin-path-decorator Source: https://docs.appsignal.com/front-end/plugins/plugin-path-decorator ## Installation Add the `@appsignal/plugin-path-decorator` and `@appsignal/javascript` packages to your `package.json`. Then, run `yarn install`/`npm install`. You can also add these packages to your `package.json` on the command line: <CodeGroup> ```bash Bash theme={null} yarn add @appsignal/javascript @appsignal/plugin-path-decorator npm install @appsignal/javascript @appsignal/plugin-path-decorator ``` </CodeGroup> ## Usage The `plugin-path-decorator` is a plugin that decorates all outgoing `Span`s with the current path. This is computed by reading from `window.location.pathname`. <CodeGroup> ```javascript JavaScript theme={null} import { plugin } from `@appsignal/plugin-path-decorator` appsignal.use(plugin(options)) ``` </CodeGroup> ## `plugin` options The plugin currently takes no options as parameters. # plugin-window-events Source: https://docs.appsignal.com/front-end/plugins/plugin-window-events The `@appsignal/plugin-window-events` plugin binds to the `window.onerror` and `window.onunhandledrejection` event handlers to catch any errors that are otherwise not caught elsewhere in your code. ## Installation Add the `@appsignal/plugin-window-events` and `@appsignal/javascript` packages to your `package.json` file and run `yarn install`/`npm install`. You can also add these packages to your `package.json` on the command line: <CodeGroup> ```bash Bash theme={null} yarn add @appsignal/javascript @appsignal/plugin-window-events npm install @appsignal/javascript @appsignal/plugin-window-events ``` </CodeGroup> ## Usage <CodeGroup> ```javascript JavaScript theme={null} import { plugin } from `@appsignal/plugin-window-events` appsignal.use(plugin(options)); ``` ### Use with Next.js Even with `"use client"`, Next.js pre-renders client components on the server, where the `window` object is not available. Guard the plugin initialization with: ```javascript JavaScript theme={null} if (typeof window !== "undefined") { appsignal.use(plugin(options)); } ``` </CodeGroup> ## `plugin` options The `plugin` can be initialized with the following options: | Param | Type | Description | | -------------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------- | | onerror | Boolean | (optional) A boolean value representing whether the plugin should bind to the `window.onerror` handler. Defaults to `true`. | | onunhandledrejection | Boolean | (optional) A boolean value representing whether the plugin should bind to the `window.onunhandledrejection` handler. Defaults to `true`. | # Sourcemaps Source: https://docs.appsignal.com/front-end/sourcemaps Sourcemaps are a way to convert backtraces from minified or transpiled JavaScript files to their original representation in your source code. A sourcemap contains data about your front-end source code, which we can use to derive the function name, line and column number, and surrounding source code from the position referenced in the backtrace. ## Requirements Enhancing backtraces with sourcemaps requires each sample to be tagged with a `revision` of your application. This is used to determine when to fetch new sourcemaps after a deploy has changed your (front-end) code. You can specify the revision in the options given when creating a new AppSignal instance. <CodeGroup> ```js JavaScript theme={null} const appsignal = new Appsignal({ key: "<your frontend API key>", revision: "<your current revision>", }); ``` </CodeGroup> ## Public sourcemaps With public sourcemaps, the sourcemap is hosted next to the JavaScript file. At the bottom of the minified JavaScript there needs to be a special comment to indicate that a sourcemap is available for the code. <CodeGroup> ```js JavaScript theme={null} //# sourceMappingURL=file.js.map ``` </CodeGroup> The URL in this comment can be a full URL to the sourcemap, or a relative path from the JavaScript file to the sourcemap. For example, if the minified JS is hosted on: `https://your.app/assets/application.min.js` and the sourcemap comment looks like `//# sourceMappingURL=application.min.js.map`, we will attempt to retrieve the source map from the following URL: `https://your.app/assets/application.min.js.map`. We attempt to cache public sourcemaps, but we may nonetheless request the minified version and the sourcemap file more than once. ## Private sourcemaps We usually recommend using public sourcemaps whenever possible, as builds that produce lots of sourcemaps can take a long time to upload via our private sourcemap endpoint. However, if that is not possible, you can also upload your sourcemaps to our [sourcemaps API endpoint](/api/sourcemaps). ### Retention Sourcemaps are grouped into a "release" by the `revision` string and we will keep the last "release" until a new `revision` is uploaded. Older "releases" will be kept for up to sixty days. # Creating and Using a Span Source: https://docs.appsignal.com/front-end/span A `Span` is the name of the object that we use to capture data about an error and its surrounding context. It is designed to be similar to, but not exactly like, the Span from the [OpenTelemetry](https://github.com/open-telemetry/opentelemetry-specification) standard specification. ## Creating a new `Span` A `Span` can be created by calling `appsignal.createSpan()`, which initializes a new `Span` object with any default options that you passed when the `Appsignal` object was initialized. <CodeGroup> ```js JavaScript theme={null} const span = appsignal.createSpan(); ``` </CodeGroup> The `createSpan()` method can also take a function as a parameter, allowing you to define the `Span`'s data as the same time as it is created. <CodeGroup> ```js JavaScript theme={null} const span = appsignal.createSpan((span) => { return span.setTags({ tag: "value", }); }); ``` </CodeGroup> `Span`s cannot be nested, nor can multiple `Span`s be passed to `appsignal.send()` at once. We recommend using `Promise.all` for concurrent `send` operations. <CodeGroup> ```js JavaScript theme={null} const span1 = appsignal.createSpan(); const span2 = appsignal.createSpan(); Promise.all([appsignal.send(span1), appsignal.send(span2)]); ``` </CodeGroup> ## Updating a `Span` After a `Span` is created, you can begin adding data to it using methods on the `Span` object: <CodeGroup> ```js JavaScript theme={null} const span = appsignal.createSpan(); span.setTags({ tag: "value" }); console.log(span.serialize().tags); // { tag: "value" } ``` </CodeGroup> Each method that modifies the `Span` returns `this`, allowing you to chain methods together: <CodeGroup> ```js JavaScript theme={null} const span = appsignal.createSpan(); span.setTags({ tag: "value" }).setError(new Error("test error")); console.log(span.serialize().tags); // { tag: "value" } console.log(span.serialize().error); // { name: "Error", message: "test error", backtrace: [...] } ``` </CodeGroup> ### `span.setAction(name: string)` Sets the `action` of the current `Span`. The `action` must never be an empty string - it can be either `undefined` or a non-empty string. An action name is used to identify the location of a certain sample error and performance issues. ### `span.setNamespace(name: string)` Sets the `namespace` of the current `Span`. Namespaces are a way to group error incidents, performance incidents, and host metrics in your app. ### `span.setError(error: Error | object)` Sets the `error` of the current `Span`. The `Error` object has a `name`, `message` and `backtrace` property. Make sure to only use something describing the error's type as the `name`. AppSignal groups the errors based on this name. You can put anything you like in the `message`. When an `Error` object is passed to the `setError` method, the `stack` property is normalised and transformed into an array of strings, with each string representing a line in the stacktrace. For consistency with our other integrations, `stack` is renamed to `backtrace`. ### `span.setTags(tags: object)` Adds `tags` to the current `Span`. The current `tags` will be merged with the `tags` object passed as a parameter. ### `span.setParams(params: object)` Adds `params` to the current `Span`. The current `params` will be merged with the `params` object passed as a parameter. <Warning> If you're using a version prior to 1.3.28, the `params` object must not contain any nested objects. </Warning> ### `span.serialize()` Returns the contents of a `Span` as an object. ## Sending a `Span` to AppSignal When you're finished adding data to the `Span`, it can then be passed to `appsignal.send()` to be pushed to our API. <CodeGroup> ```js JavaScript theme={null} const span = appsignal.createSpan((span) => { return span.setError(new Error("test error")); }); appsignal.send(span); ``` </CodeGroup> The `send()` method is different to the `sendError()` method as it allows a `Span` to be passed as a parameter, which is either pushed immediately to the API, or in the case of a network error, added to the queue to be retried later. Once the `Span` is passed to `appsignal.send()`, any [Hooks](/front-end/hooks) are applied to the `Span` in the following order: * Decorators * Optional `tags` or `namespace` arguments to `appsignal.send()` * Overrides ### About the Retry Queue If, for any reason, pushing an error to the API fails (e.g. if the network connection is not working), the `Span` object that it belongs to is placed in the retry queue. By default, requests are retried **5 times** with exponential backoff. If the request succeeds, the corresponding `Span` is removed from the queue. Once the retry limit has been reached, any `Span`s left in the queue are discarded. <Warning> No caching is currently implemented for the retry queue, meaning that if a `Span` is in the queue when the user navigates away from your application, that `Span` will also be discarded. </Warning> # Troubleshooting Source: https://docs.appsignal.com/front-end/troubleshooting ## CDN hosted assets Your app's assets are hosted on a CDN and you see the following warning message in the browser's web console: <CodeGroup> ```sh Shell theme={null} Cross-domain or eval script error detected, error ignored ``` </CodeGroup> This is normal browser behaviour and is a consequence of the [Same-Origin Policy](https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy), a security measure designed to protect your users from [Cross-Site Request Forgery](/appsignal/terminology#cross-site-request-forgery) (CSRF) attacks. Luckily, this is a fairly easy problem to remedy. First, on your CDN, add a cross-origin (CORS) header: <CodeGroup> ```sh Shell theme={null} Access-Control-Allow-Origin: * ``` </CodeGroup> In your app, make sure the `crossorigin` attribute is present in all your JavaScript tags. <CodeGroup> ```html HTML theme={null} <script type="text/javascript" src="//cdn.example.com/bundle.js" crossorigin="anonymous"> ``` </CodeGroup> Or if you are using a Rails helper: <CodeGroup> ```ruby Ruby theme={null} <%= javascript_include_tag "application", :crossorigin => :anonymous %> ``` </CodeGroup> ## Content Security Policy (CSP) Your Application's content Security Policy might prevent the error tracking library from sending data to our `https://appsignal-endpoint.net` endpoint. > Content Security Policy (CSP) is an added layer of security that helps to detect and mitigate certain types of attacks, including Cross Site Scripting (XSS) and data injection attacks. These attacks are used for everything from data theft to site defacement to distribution of malware. > > <cite> > [https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP)](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) > </cite> Make sure to add `https://appsignal-endpoint.net` to your Content Security Policy header, if present. With just AppSignal in the header: ```sh Shell theme={null} Content-Security-Policy: connect-src 'self' https://appsignal-endpoint.net ``` Or, with other content in the header: ```sh Shell theme={null} Content-Security-Policy: <other_content>; connect-src 'self' https://appsignal-endpoint.net ``` # AppSignal Documentation Source: https://docs.appsignal.com/getting-started Learn how to set up error tracking, performance monitoring, logging, and more for your application. AppSignal is an application monitoring platform that provides error tracking, performance monitoring, logging, and uptime monitoring for your projects. This documentation covers everything from initial setup to advanced configuration. <Note> πŸ›Ÿ Looking for help? Check out the [support](#support) section. </Note> ## Getting Started New to AppSignal? The guides below walk you through all the steps required to set up AppSignal with your application. <Card title="AppSignal Guides" icon="book-open" href="/guides"> Step-by-step walkthroughs for setting up AppSignal in your application. </Card> ### YouTube β€” AppSignal in 5 minutes: A quick start guide <Frame> <iframe title="YouTube video player" /> </Frame> [Watch on YouTube β†’](https://www.youtube.com/watch?v=hetBXN5db8k) ## Languages Everything you need to know when integrating AppSignal with your application's programming language. ### Native integrations AppSignal's own SDKs with the deepest feature coverage. <CardGroup> <Card title="Ruby" icon="gem" href="/ruby"> * [AppSignal for Ruby](/ruby) * [Installation](/ruby/installation) * [Configuration](/ruby/configuration) * [Custom instrumentation](/ruby/instrumentation) * [Example applications](https://github.com/appsignal/appsignal-examples#ruby-example-apps) </Card> <Card title="Elixir" icon="droplet" href="/elixir"> * [AppSignal for Elixir](/elixir) * [Installation](/elixir/installation) * [Configuration](/elixir/configuration) * [Custom instrumentation](/elixir/instrumentation) * [Command line tools](/elixir/command-line) </Card> <Card title="Node.js" icon="node-js" href="/nodejs/3.x"> * [AppSignal for Node.js](/nodejs/3.x) * [Installation guides](/nodejs/3.x/installation) * [Configuration](/nodejs/3.x/configuration) * [Custom instrumentation](/nodejs/3.x/instrumentation) * [Command line tools](/nodejs/3.x/command-line) </Card> <Card title="Python" icon="python" href="/python"> * [AppSignal for Python](/python) * [Installation guides](/python/installation) * [Configuration](/python/configuration) * [Custom instrumentation](/python/instrumentation) * [Instrumentations](/python/instrumentations) </Card> <Card title="PHP" icon="php" href="/php"> * [AppSignal for PHP](/php) * [Installation](/php/installation) * [Configuration](/php/configuration) * [Custom instrumentation](/php/instrumentation) * [Integrations](/php/integrations) </Card> <Card title="JavaScript (Browser)" icon="js" href="/front-end"> * [AppSignal for Front-end](/front-end) * [Installation](/front-end/installation) * [Configuration](/front-end/configuration) * [Integrations](/front-end/integrations) * [Troubleshooting](/front-end/troubleshooting) </Card> </CardGroup> ### Via OpenTelemetry AppSignal supports additional languages through OpenTelemetry. Any tool or service that exports OpenTelemetry data, including traces, metrics, and logs, can send it to AppSignal. <CardGroup> <Card title="Go" icon="golang" href="/go"> * [AppSignal for Go](/go) * [Installation](/go/installation) * [Configuration](/go/configuration) * [Custom instrumentation](/go/custom-instrumentation) * [Instrumentations](/go/instrumentations) </Card> <Card title="Java" icon="java" href="/java"> * [AppSignal for Java](/java) * [Installation](/java/installation) * [Configuration](/java/configuration) * [Custom instrumentation](/java/custom-instrumentation) * [Instrumentations](/java/instrumentations) </Card> <Card title="Other languages (via OpenTelemetry)" icon="telescope" href="/opentelemetry"> * [OpenTelemetry overview](/opentelemetry) * [Installation](/opentelemetry/installation) * [Configuration](/opentelemetry/configuration) * [Custom instrumentation](/opentelemetry/custom-instrumentation) * [Troubleshooting](/opentelemetry/troubleshooting) </Card> </CardGroup> ## Features Extend your AppSignal integration with additional observability features and workflow tools. <CardGroup> <Card title="Observability" icon="chart-line"> * [Logging](/logging) * [Host Metrics](/metrics/host-metrics) * [Custom Metrics](/metrics/custom) * [Standalone Agent](/standalone-agent/installation) * [AppSignal API](/api) </Card> <Card title="Alerting & Monitoring" icon="bell"> * [Anomaly Detection](/anomaly-detection) * [Uptime Monitoring](/uptime-monitoring/setup) * [Process Monitoring](/check-ins) </Card> <Card title="Workflow Integrations" icon="plug"> * [Discord](/application/integrations/discord) * [GitHub](/application/integrations/github) * [Jira](/application/integrations/jira) * [Slack](/application/integrations/slack) * [All Integrations](/services-integrations) </Card> </CardGroup> ## Business Add-Ons AppSignal offers Business Add-Ons for additional monitoring needs. * [HIPAA Business Associate Agreement](/support/business-add-ons#hipaa-business-associate-agreement) * [Long-Term Log Storage](/support/business-add-ons#long-term-log-storage) ## Support Need help? The resources below can help you troubleshoot issues and reach our support team. * [Contact Us](mailto:support@appsignal.com) * [Debugging Guide](/support/debugging) * [Known Issues](/support/known-issues) * [Supported Operating Systems](/support/operating-systems) * [Maintenance Policy](/support/maintenance-policy) * [Security Overview](/appsignal/security) * [AppSignal Status Page](https://status.appsignal.com) # AppSignal for Go Source: https://docs.appsignal.com/go AppSignal supports Go through OpenTelemetry. This will allow you to send trace, metric, and log data from your Go application to AppSignal via OpenTelemetry. ## We want your feedback! Our OpenTelemetry support is relatively new and we haven't tested it yet with all the different setups out there. Some features may not work with OpenTelemetry data yet. If you encounter any issues or have suggestions for improvement, please contact support or join our Discord server. <CardGroup> <Card title="Contact support" icon="envelope" href="mailto:support@appsignal.com?subject=OpenTelemetry" /> <Card title="Join our Discord" icon="discord" href="https://discord.gg/VreYMePw9e" /> </CardGroup> ## Setting up OpenTelemetry Follow the installation instructions in the next step to set up OpenTelemetry in your application and report data to AppSignal. # AppSignal Go Configuration Source: https://docs.appsignal.com/go/configuration In this documentation, we'll explain how to configure OpenTelemetry in your application, the available options, and the minimal configuration required. The configuration options for the OpenTelemetry resource, set by the OpenTelemetry exporter, can be found on the [configuration options page](/go/configuration/options). To configure the AppSignal collector, the program used to send data to AppSignal, please refer to the [collector's configuration documentation](/collector/configuration). # Go configuration options Source: https://docs.appsignal.com/go/configuration/options AppSignal for Go can be configured through OpenTelemetry resource attributes. Resource attributes are attributes that apply that every trace reported from the application using OpenTelemetry. These resource attributes should be configured in your application, where you also configure the OpenTelemetry exporter to export to the [AppSignal collector](/go/installation). To configure the resource attributes, add a resource to your tracer provider like shown below. ```go Go theme={null} import ( // Other imports here... // Import these OpenTelemetry packages "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp" "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp" "go.opentelemetry.io/otel/exporters/otlp/otlptrace" "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp" "go.opentelemetry.io/otel/log/global" "go.opentelemetry.io/otel/propagation" sdklog "go.opentelemetry.io/otel/sdk/log" sdkmetric "go.opentelemetry.io/otel/sdk/metric" sdkresource "go.opentelemetry.io/otel/sdk/resource" sdktrace "go.opentelemetry.io/otel/sdk/trace" ) func initTracer() func(context.Context) error { // OpenTelemetry config setup here resource, err := sdkresource.Merge( sdkresource.Default(), sdkresource.NewSchemaless( resource.WithAttributes(attribute.String("appsignal.config.name", "My app name")), // And other resource attributes ), ) tracerProvider := sdktrace.NewTracerProvider( // Including other `.With...` function calls sdktrace.WithResource(resource), ) // Followed by the rest of the OpenTelemetry config } ``` ## Available options * Required options * [`environment`](#option-environment) * [`host.name`](#option-host.name) * [`language_integration`](#option-language_integration) * [`name`](#option-name) * [`push_api_key`](#option-push_api_key) * [`revision`](#option-revision) * [`service.name`](#option-service.name) * Options * [`app_path`](#option-app_path) * [`filter_attributes`](#option-filter_attributes) * [`filter_function_parameters`](#option-filter_function_parameters) * [`filter_request_payload`](#option-filter_request_payload) * [`filter_request_query_parameters`](#option-filter_request_query_parameters) * [`filter_request_session_data`](#option-filter_request_session_data) * [`ignore_actions`](#option-ignore_actions) * [`ignore_errors`](#option-ignore_errors) * [`ignore_logs`](#option-ignore_logs) * [`ignore_namespaces`](#option-ignore_namespaces) * [`request_headers`](#option-request_headers) * [`response_headers`](#option-response_headers) * [`send_function_parameters`](#option-send_function_parameters) * [`send_request_payload`](#option-send_request_payload) * [`send_request_query_parameters`](#option-send_request_query_parameters) * [`send_request_session_data`](#option-send_request_session_data) ## environment <a /> | Field | Value | | ---------------------- | ------------------------------ | | Resource attribute key | `appsignal.config.environment` | | Required | yes | | Type | `String` | | Default value | nil (This is unset by default) | ### Description The environment of the app to be reported to AppSignal. ```go Go theme={null} resource, err := sdkresource.Merge( sdkresource.Default(), sdkresource.NewSchemaless( resource.WithAttributes(attribute.String("appsignal.config.environment", "production")), // And other resource attributes ), ) ``` <Note> **Note**: Changing the [name](#option-name) or environment of an existing app will create a new app on AppSignal.com. </Note> ## host.name <a /> | Field | Value | | ---------------------- | -------------------- | | Resource attribute key | `host.name` | | Required | yes | | Type | `String` | | Default value | detected from system | ### Description The `host.name` resource attribute helps AppSignal recognize different hosts for traces and tag the traces automatically with the hostname. ```go Go theme={null} resource, err := sdkresource.Merge( sdkresource.Default(), sdkresource.NewSchemaless( resource.WithAttributes(attribute.String("host.name", "my-hostname")), // And other resource attributes ), ) ``` ## language\_integration <a /> | Field | Value | | ---------------------- | --------------------------------------- | | Resource attribute key | `appsignal.config.language_integration` | | Required | yes | | Type | `String` | | Default value | nil (This is unset by default) | ### Description AppSignal uses the `language_integration` resource attribute to detect the language of a trace and correctly parse exception backtraces. To set this option, specify the language name in lowercase format: `go`. ```go Go theme={null} resource, err := sdkresource.Merge( sdkresource.Default(), sdkresource.NewSchemaless( resource.WithAttributes(attribute.String("appsignal.config.language_integration", "go")), // And other resource attributes ), ) ``` ## name <a /> | Field | Value | | ---------------------- | ------------------------------ | | Resource attribute key | `appsignal.config.name` | | Required | yes | | Type | `String` | | Default value | nil (This is unset by default) | ### Description Name of your application as it should be displayed on AppSignal.com. ```go Go theme={null} resource, err := sdkresource.Merge( sdkresource.Default(), sdkresource.NewSchemaless( resource.WithAttributes(attribute.String("appsignal.config.name", "My awesome app")), // And other resource attributes ), ) ``` <Note> **Note**: Changing the name or [environment](#option-env) of an existing app will create a new app on AppSignal.com. </Note> ## push\_api\_key <a /> | Field | Value | | ---------------------- | ------------------------------- | | Resource attribute key | `appsignal.config.push_api_key` | | Required | yes | | Type | `String` | | Default value | nil (This is unset by default) | ### Description The organization-level authentication key to authenticate with our Push API. Read more about the [AppSignal Push API key](/appsignal/terminology#push-api-key). ```go Go theme={null} resource, err := sdkresource.Merge( sdkresource.Default(), sdkresource.NewSchemaless( resource.WithAttributes(attribute.String("appsignal.config.push_api_key", "00000000-0000-0000-0000-000000000000")), // And other resource attributes ), ) ``` ## revision <a /> | Field | Value | | ---------------------- | ------------------------------ | | Resource attribute key | `appsignal.config.revision` | | Required | yes | | Type | `String` | | Default value | nil (This is unset by default) | ### Description Set the app revision to report the currently running version of your app. AppSignal will create a deploy marker when this value changes, and tag all incoming data with the current revision. Read more about deploy markers in the [deploy markers topic](/application/markers/deploy-markers). ```go Go theme={null} import ( "os/exec" // And other imports ) var revision string cmd := exec.Command("git", "rev-parse", "--short", "HEAD") output, err := cmd.Output() if err != nil { revision = "unknown" } else { revision = strings.TrimSpace(string(output)) } resource, err := sdkresource.Merge( sdkresource.Default(), sdkresource.NewSchemaless( resource.WithAttributes(attribute.String("appsignal.config.revision", revision)), // And other resource attributes ), ) ``` ## service.name <a /> | Field | Value | | ---------------------- | ------------------------------ | | Resource attribute key | `service.name` | | Required | yes | | Type | `String` | | Default value | nil (This is unset by default) | ### Description The `service.name` resource attribute helps AppSignal recognize different services for traces and groups the traces automatically in a namespace based on the service name. Choose a name that fits your application, like "Web server", "Background worker", "Email service", "Authentication service", etc. ```go Go theme={null} resource, err := sdkresource.Merge( sdkresource.Default(), sdkresource.NewSchemaless( resource.WithAttributes(attribute.String("service.name", "My service name")), // And other resource attributes ), ) ``` ## app\_path <a /> | Field | Value | | ---------------------- | ------------------------------ | | Resource attribute key | `appsignal.config.app_path` | | Required | no | | Type | `String` | | Default value | nil (This is unset by default) | ### Description The location of the app on the host's file system. The `app_path` resource attribute helps AppSignal clean up backtraces by stripping away the absolute app path of backtrace lines. This way only paths within the context of the project directory is shown. This makes our [Backtrace links](/application/backtrace-links) feature possible. ```go Go theme={null} import ( "os" // And other imports ) resource, err := sdkresource.Merge( sdkresource.Default(), sdkresource.NewSchemaless( resource.WithAttributes(attribute.String("appsignal.config.app_path", os.Getenv("PWD"))), // And other resource attributes ), ) ``` ## filter\_attributes <a /> | Field | Value | | ---------------------- | ------------------------------------ | | Resource attribute key | `appsignal.config.filter_attributes` | | Required | no | | Type | `list(String)` | | Default value | `[]` | ### Description The `filter_attributes` resource attribute allows you to filter out specific attributes from being reported to AppSignal. This can be useful to filter out sensitive or non-relevant information from being reported. If an attribute is filtered out this way, it will not show up in the interface at all. ```go Go theme={null} resource, err := sdkresource.Merge( sdkresource.Default(), sdkresource.NewSchemaless( resource.WithAttributes(attribute.StringSlice("appsignal.config.filter_attributes", []string{"my.secret.attribute", "some.opentelemetry.attribute"})), // And other resource attributes ), ) ``` ## filter\_function\_parameters <a /> | Field | Value | | ---------------------- | --------------------------------------------- | | Resource attribute key | `appsignal.config.filter_function_parameters` | | Required | no | | Type | `list(String)` | | Default value | `[]` | ### Description This resource attribute allows you to filter out any function parameters set in the [`appsignal.function.parameters` span attribute](/guides/custom-data/function-parameters). In the example below, values for the keys listed in the `filter_function_parameters` config option are replaced with `[FILTERED]`. ```go Go theme={null} resource, err := sdkresource.Merge( sdkresource.Default(), sdkresource.NewSchemaless( resource.WithAttributes(attribute.StringSlice("appsignal.config.filter_function_parameters", []string{"api_token", "secret"})), // And other resource attributes ), ) ``` ## filter\_request\_payload <a /> | Field | Value | | ---------------------- | ----------------------------------------- | | Resource attribute key | `appsignal.config.filter_request_payload` | | Required | no | | Type | `list(String)` | | Default value | `[]` | ### Description This resource attribute allows you to filter out any request payload data set in the [`appsignal.request.payload` span attribute](/guides/custom-data/request-parameters). In the example below, values for the keys listed in the `filter_request_payload` config option are replaced with `[FILTERED]`. Read more about [request query parameter filtering](/application/parameter-filtering). ```go Go theme={null} resource, err := sdkresource.Merge( sdkresource.Default(), sdkresource.NewSchemaless( resource.WithAttributes(attribute.StringSlice("appsignal.config.filter_request_payload", []string{"password", "cvv"})), // And other resource attributes ), ) ``` ## filter\_request\_query\_parameters <a /> | Field | Value | | ---------------------- | -------------------------------------------------- | | Resource attribute key | `appsignal.config.filter_request_query_parameters` | | Required | no | | Type | `list(String)` | | Default value | `[]` | ### Description This resource attribute allows you to filter out any request query parameters set in the [`appsignal.request.query_parameters` span attribute](/guides/custom-data/request-parameters). In the example below, values for the keys listed in the `filter_request_query_parameters` config option are replaced with `[FILTERED]`. Read more about [request query parameter filtering](/application/parameter-filtering). ```go Go theme={null} resource, err := sdkresource.Merge( sdkresource.Default(), sdkresource.NewSchemaless( resource.WithAttributes(attribute.StringSlice("appsignal.config.filter_request_query_parameters", []string{"password", "cvv"})), // And other resource attributes ), ) ``` ## filter\_request\_session\_data <a /> | Field | Value | | ---------------------- | ---------------------------------------------- | | Resource attribute key | `appsignal.config.filter_request_session_data` | | Required | no | | Type | `list(String)` | | Default value | `[]` | ### Description The `filter_request_session_data` resource attribute allows you to filter out any request session data set in the [`appsignal.request.session_data` span attribute](/guides/custom-data/request-session-data). In the example below, values for the keys listed in the `filter_request_session_data` config option are replaced with `[FILTERED]`. Read more about [request session data filtering](/application/session-data-filtering). ```go Go theme={null} resource, err := sdkresource.Merge( sdkresource.Default(), sdkresource.NewSchemaless( resource.WithAttributes(attribute.StringSlice("appsignal.config.filter_session_data", []string{"password", "cvv"})), // And other resource attributes ), ) ``` ## ignore\_actions <a /> | Field | Value | | ---------------------- | --------------------------------- | | Resource attribute key | `appsignal.config.ignore_actions` | | Required | no | | Type | `list(String)` | | Default value | `[]` | ### Description With this config option you can specify a list of actions that will be ignored by AppSignal. Everything that happens including exceptions will not be transmitted to AppSignal. This can be useful to ignore health check endpoints or other actions that you don't want to monitor. Read more about [ignoring actions](/guides/filter-data/ignore-actions). ```go Go theme={null} resource, err := sdkresource.Merge( sdkresource.Default(), sdkresource.NewSchemaless( resource.WithAttributes(attribute.StringSlice("appsignal.config.ignore_actions", []string{"GET /heath_check", "POST /ping"})), // And other resource attributes ), ) ``` ## ignore\_errors <a /> | Field | Value | | ---------------------- | -------------------------------- | | Resource attribute key | `appsignal.config.ignore_errors` | | Required | no | | Type | `list(String)` | | Default value | `[]` | ### Description This config option allows you to ignore specific errors from being reported to AppSignal. This can be useful to ignore expected errors or errors that can't be solved. Read more about [ignoring errors](/guides/filter-data/ignore-errors). ```go Go theme={null} resource, err := sdkresource.Merge( sdkresource.Default(), sdkresource.NewSchemaless( resource.WithAttributes(attribute.StringSlice("appsignal.config.ignore_errors", []string{"MyCustomError", "ExpectedError"})), // And other resource attributes ), ) ``` ## ignore\_logs <a /> | Field | Value | | ---------------------- | ------------------------------ | | Resource attribute key | `appsignal.config.ignore_logs` | | Required | no | | Type | `list(String)` | | Default value | `[]` | ### Description List of log messages that will be ignored. Any log message containing any of the elements of the list will not be transmitted to AppSignal. A small subset of regex syntax is supported, read more about it in our [Ignore Logs](/guides/filter-data/ignore-logs) guide. ```go Go theme={null} resource, err := sdkresource.Merge( sdkresource.Default(), sdkresource.NewSchemaless( resource.WithAttributes(attribute.StringSlice("appsignal.config.ignore_logs", []string{"^done$", "Task .* completed successfully"})), // And other resource attributes ), ) ``` ## ignore\_namespaces <a /> | Field | Value | | ---------------------- | ------------------------------------ | | Resource attribute key | `appsignal.config.ignore_namespaces` | | Required | no | | Type | `list(String)` | | Default value | `[]` | ### Description This config option allows you to ignore specific namespaces from being reported to AppSignal. This can be useful to ignore specific parts of your application from being monitored. Read more about [namespaces](/application/namespaces). ```go Go theme={null} resource, err := sdkresource.Merge( sdkresource.Default(), sdkresource.NewSchemaless( resource.WithAttributes(attribute.StringSlice("appsignal.config.ignore_namespaces", []string{"admin", "secret"})), // And other resource attributes ), ) ``` ## request\_headers <a /> | Field | Value | | ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | | Resource attribute key | `appsignal.config.request_headers` | | Required | no | | Type | `list(String)` | | Default value | `["accept", "accept-charset", "accept-encoding", "accept-language", "cache-control", "connection", "content-length", "host", "range"]` | ### Description Configure which request headers to include when a request is made to an HTTP server. This option is an allowlist. It only includes the headers that are configured. If the list is empty, no headers are included. The request headers are read from the `http.request.header.<key>` [OpenTelemetry span attributes](https://opentelemetry.io/docs/specs/semconv/http/http-spans/), where `<key>` is the normalized header name (lowercase). To not set any headers, explicitly set the resource attribute value to an empty array. ```go Go theme={null} resource, err := sdkresource.Merge( sdkresource.Default(), sdkresource.NewSchemaless( // Only send these specific headers resource.WithAttributes(attribute.StringSlice("appsignal.config.request_headers", []string{"accept", "request_method", "content_length"})), // Do not send any headers // resource.WithAttributes(attribute.StringSlice("appsignal.config.request_headers", []string{})), // And other resource attributes ), ) ``` ## response\_headers <a /> | Field | Value | | ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | | Resource attribute key | `appsignal.config.response_headers` | | Required | no | | Type | `list(String)` | | Default value | `["accept", "accept-charset", "accept-encoding", "accept-language", "cache-control", "connection", "content-length", "host", "range"]` | ### Description Configure which response headers to include when a request is made by an HTTP client. This option is an allowlist. It only includes the headers that are configured. If the list is empty, no headers are included. The response headers are read from the `http.response.header.<key>` [OpenTelemetry span attributes](https://opentelemetry.io/docs/specs/semconv/http/http-spans/), where `<key>` is the normalized header name (lowercase). To not set any headers, explicitly set the resource attribute value to an empty array. ```go Go theme={null} resource, err := sdkresource.Merge( sdkresource.Default(), sdkresource.NewSchemaless( // Only send these specific headers resource.WithAttributes(attribute.StringSlice("appsignal.config.response_headers", []string{"accept", "request_method", "content_length"})), // Do not send any headers // resource.WithAttributes(attribute.StringSlice("appsignal.config.response_headers", []string{})), // And other resource attributes ), ) ``` ## send\_function\_parameters <a /> | Field | Value | | ---------------------- | ------------------------------------------- | | Resource attribute key | `appsignal.config.send_function_parameters` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `true` | ### Description Configure whether to include function parameters in traces. If set to `false` no such data is sent to our servers. These values are set with the [`appsignal.function.parameters` span attribute](/guides/custom-data/function-parameters). ```go Go theme={null} resource, err := sdkresource.Merge( sdkresource.Default(), sdkresource.NewSchemaless( resource.WithAttributes(attribute.Bool("appsignal.config.send_function_parameters", false)), // And other resource attributes ), ) ``` ## send\_request\_payload <a /> | Field | Value | | ---------------------- | --------------------------------------- | | Resource attribute key | `appsignal.config.send_request_payload` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `true` | ### Description Configure whether to send request payload data in traces. If set to `false` no such data is sent to our servers. These values are set with the [`appsignal.request.payload` span attribute](/guides/custom-data/request-parameters). For more information please read about [request payload filtering](/application/parameter-filtering). ```go Go theme={null} resource, err := sdkresource.Merge( sdkresource.Default(), sdkresource.NewSchemaless( resource.WithAttributes(attribute.Bool("appsignal.config.send_request_payload", false)), // And other resource attributes ), ) ``` ## send\_request\_query\_parameters <a /> | Field | Value | | ---------------------- | ------------------------------------------------ | | Resource attribute key | `appsignal.config.send_request_query_parameters` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `true` | ### Description Configure whether to include request query parameters in traces. If set to `false` no such data is sent to our servers. These values are set with the [`appsignal.request.query_parameters` span attribute](/guides/custom-data/request-parameters). For more information please read about [request parameter filtering](/application/parameter-filtering). ```go Go theme={null} resource, err := sdkresource.Merge( sdkresource.Default(), sdkresource.NewSchemaless( resource.WithAttributes(attribute.Bool("appsignal.config.send_request_query_parameters", false)), // And other resource attributes ), ) ``` ## send\_request\_session\_data <a /> | Field | Value | | ---------------------- | -------------------------------------------- | | Resource attribute key | `appsignal.config.send_request_session_data` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `true` | ### Description Configure whether to send request session data in traces. If set to `false` no such data is sent to our servers. These values are set with the [`appsignal.request.session_data` span attribute](/guides/custom-data/request-session-data). For more information please read about [request session data filtering](/application/session-data-filtering). ```go Go theme={null} resource, err := sdkresource.Merge( sdkresource.Default(), sdkresource.NewSchemaless( resource.WithAttributes(attribute.Bool("appsignal.config.send_session_data", false)), // And other resource attributes ), ) ``` # Go Custom Instrumentation Source: https://docs.appsignal.com/go/custom-instrumentation AppSignal is compatible with OpenTelemetry instrumentation packages. Some of these [instrumentation packages](/go/instrumentations) may require additional setup. This does not always include the information you need to debug issues. For more fine-grained reporting, you can add custom instrumentation. We support [OpenTelemetry tracing][manual] as laid out in the OpenTelemetry documentation. It's possible to add more data to span using OpenTelemetry span attributes. There are also AppSignal span attributes that can change how traces are grouped and some attributes that allow for filtering out sensitive data. ## Setup When adding custom instrumentation, first import the OpenTelemetry trace package in the file you want to add the instrumentation to. <CodeGroup> ```go Go theme={null} import ( "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" ) ``` </CodeGroup> ## Creating a new span Using the tracer initialized during the [installation](/go/installation), create a new span. <CodeGroup> ```go Go theme={null} var tracer = otel.Tracer("my-tracer-name") func httpHandler(w http.ResponseWriter, r *http.Request) { // Create a new span from the parent context ctx, span := tracer.Start(r.Context(), "hello-span") // Defer closing the span to the end of this function defer span.End() // Set attributes } ``` </CodeGroup> *Note: In these examples we're relying on the context from the HTTP request, given by `r.Context()`.* *Receiving the context may be different in your application.* ## Get the current span You can also fetch the current span using the tracer initialized during the [installation](/go/installation): <CodeGroup> ```go Go theme={null} func httpHandler(w http.ResponseWriter, r *http.Request) { ctx := r.Context() span := trace.SpanFromContext(ctx) // Set attributes } ``` </CodeGroup> *Note: This will only return a span if one is already active.* More ways to create and get spans are documented on the [OpenTelemetry Go Instrumentation page][manual]. ## AppSignal attributes Once you have created, or fetched, a span, you can set certain attributes that are specific to AppSignal to customize how the data arrives in AppSignal. <CodeGroup> ```go Go theme={null} span = // Create a new span or fetch the current span span.SetAttributes(attribute.String("attribute_name", "attribute value")) ``` </CodeGroup> See our guides for more information on what custom AppSignal attributes are supported: * [Tagging guide](/guides/tagging) * [Data customization guide](/guides/custom-data) [manual]: https://opentelemetry.io/docs/languages/go/instrumentation/ # OpenTelemetry Go Installation Source: https://docs.appsignal.com/go/installation Please follow the [installation guide](/guides/new-application) first, when adding a new application to AppSignal. Then make sure to [install the AppSignal collector](/collector/installation) before proceeding. ## Configure OpenTelemetry in your application OpenTelemetry must be initialized before your application starts, to ensure that all telemetry data is sent through the exporter to AppSignal. For example, in a web application, OpenTelemetry must be initialized before the routes are loaded and the server starts. Create an `initOpenTelemetry()` function like the one in the example below and add it to your application's main file. Make sure to update the values below with your AppSignal application name, environment and push API key, and to replace the exporter endpoint with the address of your AppSignal collector if needed. <CodeGroup> ```go Go theme={null} package main import ( // Import these standard libraries used in the OpenTelemetry configuration "context" "log" "os" "os/exec" "strings" // Import these OpenTelemetry libraries "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp" "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp" "go.opentelemetry.io/otel/exporters/otlp/otlptrace" "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp" "go.opentelemetry.io/otel/log/global" "go.opentelemetry.io/otel/propagation" sdklog "go.opentelemetry.io/otel/sdk/log" sdkmetric "go.opentelemetry.io/otel/sdk/metric" sdkresource "go.opentelemetry.io/otel/sdk/resource" sdktrace "go.opentelemetry.io/otel/sdk/trace" ) func initOpenTelemetry() func() { // Replace these values with your AppSignal application name, environment // and push API key. These are used by the resource attributes configuration below. name := "My app" push_api_key := "0000-0000-0000-0000" environment := "development" // Set the name of the service that is being monitored. A common choice is the // name of the framework used. This is used to group traces and metrics in AppSignal. service_name := "My service name" // Replace `localhost:8099` with the address of your AppSignal collector // if it's running on another host. endpoint := "localhost:8099" hostname, err := os.Hostname() if err != nil { hostname = "unknown" } var revision string cmd := exec.Command("git", "rev-parse", "--short", "HEAD") output, err := cmd.Output() if err != nil { revision = "unknown" } else { revision = strings.TrimSpace(string(output)) } resource, err := sdkresource.Merge( sdkresource.Default(), sdkresource.NewSchemaless( attribute.String("appsignal.config.name", name), attribute.String("appsignal.config.environment", environment), attribute.String("appsignal.config.push_api_key", push_api_key), attribute.String("appsignal.config.revision", revision), attribute.String("appsignal.config.language_integration", "go"), attribute.String("appsignal.config.app_path", os.Getenv("PWD")), attribute.String("service.name", service_name), attribute.String("host.name", hostname), ), ) if err != nil { log.Fatalf("Error creating OTLP resource: %v", err) } // Tracing traceClient := otlptracehttp.NewClient( otlptracehttp.WithInsecure(), // Remove if the collector is accessible via HTTPS otlptracehttp.WithEndpoint(endpoint), ) traceExporter, err := otlptrace.New(context.Background(), traceClient) if err != nil { log.Fatalf("Error creating OTLP trace exporter: %v", err) } tracerProvider := sdktrace.NewTracerProvider( sdktrace.WithBatcher(traceExporter), sdktrace.WithResource(resource), ) otel.SetTracerProvider(tracerProvider) otel.SetTextMapPropagator( propagation.NewCompositeTextMapPropagator( propagation.TraceContext{}, propagation.Baggage{}, ), ) // Metrics metricExporter, err := otlpmetrichttp.New( context.Background(), otlpmetrichttp.WithInsecure(), // Remove if the collector is accessible via HTTPS otlpmetrichttp.WithEndpoint(endpoint), ) if err != nil { log.Fatalf("creating OTLP metric exporter: %v", err) } meterProvider := sdkmetric.NewMeterProvider( sdkmetric.WithReader(sdkmetric.NewPeriodicReader(metricExporter)), sdkmetric.WithResource(resource), ) otel.SetMeterProvider(meterProvider) // Logs logExporter, err := otlploghttp.New( context.Background(), otlploghttp.WithInsecure(), // Remove if the collector is accessible via HTTPS otlploghttp.WithEndpoint(endpoint), ) if err != nil { log.Fatalf("creating OTLP log exporter: %v", err) } loggerProvider := sdklog.NewLoggerProvider( sdklog.WithResource(resource), sdklog.WithProcessor( sdklog.NewBatchProcessor(logExporter), ), ) global.SetLoggerProvider(loggerProvider) // Cleanup return func() { ctx := context.Background() if err := tracerProvider.Shutdown(ctx); err != nil { log.Println("Error shutting down tracer provider:", err) } if err := meterProvider.Shutdown(ctx); err != nil { log.Println("Error shutting down meter provider:", err) } if err := loggerProvider.Shutdown(ctx); err != nil { log.Println("Error shutting down logger provider:", err) } } } func main() { cleanup := initOpenTelemetry() defer cleanup() // ... your application's initialization code } ``` </CodeGroup> *If your collector is accessible through HTTPS, remove the three lines that contain the `WithInsecure()` method call in the example config.* To install the OpenTelemetry libraries imported in the example above, run this command. <CodeGroup> ```sh Shell theme={null} go mod tidy ``` </CodeGroup> ## Configure OpenTelemetry instrumentation packages The OpenTelemetry stack will not emit any data by itself. To instrument your application, install and configure the instrumentation packages for the libraries and frameworks used by your application. You can [find OpenTelemetry instrumentation packages at the OpenTelemetry registry](https://opentelemetry.io/ecosystem/registry/?s=\&component=instrumentation\&language=go\&flag=all). For some popular OpenTelemetry instrumentations, you can find specific configuration instructions in these pages: * [Gin-gonic](/go/instrumentations/gin-gonic) * [Gorilla mux](/go/instrumentations/gorilla-mux) * [MongoDB](/go/instrumentations/mongo) * [Redis](/go/instrumentations/redis) * [SQL](/go/instrumentations/sql) ## Test the app! Now that all the components are connected, start your app and test if you see data arrive in AppSignal. Check the ["Errors > Issue list"](https://appsignal.com/redirect-to/app?to=exceptions) and ["Performance > Traces"](https://appsignal.com/redirect-to/app?to=performance/traces) page specifically. If after following our installation instructions you still don't see data in AppSignal, [let us know](mailto:support@appsignal.com?subject=OpenTelemetry%20beta%20issue) and we'll help you finalize your OpenTelemetry installation! ## Add Instrumentation Packages The next step is to instrument Go packages like Gin-gonic, Gorilla, etc. This will provide much more data to really dig into the performance of your applications. The steps for every package are usually as follows: * Install the OpenTelemetry instrumentation package for the library you want to instrument. * Follow the installation instructions for the instrumentation package. For more installation and configuration information per library, please consult the [Go instrumentations section][instrumentations]. [Go language]: https://go.dev/ [OpenTelemetry]: https://opentelemetry.io/ [instrumentations]: /go/instrumentations.html # Go Instrumentations Source: https://docs.appsignal.com/go/instrumentations <Tip> Learn more about why [adding additional instrumentation](/guides/instrumentation/additional-opentelemetry-instrumentation) to your application is recommended. </Tip> This page lists some of OpenTelemetry for Go instrumentations that AppSignal supports. The documentation page for each library contains extra steps to instrument the package, such as which packages to include and how to report request parameters. The full list of available instrumentation packages for Go can be found on the [OpenTelemetry registry for Go](https://opentelemetry.io/ecosystem/registry/?language=go\&component=instrumentation), along with their installation instructions, and example apps. <Note> Is your app not reporting the data you'd like to see? Don't hesitate to [contact us](mailto:support@appsignal.com) and let us know which libraries you're using. We'll try to help get more useful data reported. </Note> ## Additional Go library instrumentations * [Gorilla Mux](/go/instrumentations/gorilla-mux) * [Gin-gonic](/go/instrumentations/gin-gonic) * [Mongo](/go/instrumentations/mongo) * [Redis](/go/instrumentations/redis) * [SQL](/go/instrumentations/sql) # Gin-gonic Instrumentation Source: https://docs.appsignal.com/go/instrumentations/gin-gonic [Gin-gonic](https://gin-gonic.com) is a full featured web framework for Go. Data reported from Gin-gonic is supported by AppSignal. This page will help you get set up to instrument Gin-gonic applications and report request parameters and payloads. ## Setup To instrument your Go-gin application, you'll need to import the OpenTelemetry official instrumentation package: <CodeGroup> ```go Go theme={null} import "go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin" ``` </CodeGroup> The Go-gin instrumentation is packaged as a router middleware, as you can see in the example below, the tracer initialization is called before anything as described in more detail in the [Go installation](/go/installation) page. Adding `otelgin.Middleware()` to your app router is all that you need to get all your requests instrumented. <CodeGroup> ```go Go theme={null} func main() { cleanup := initOpenTelemetry() defer cleanup() router := gin.New() // This middleware must be added before any middlewares or routes router.Use(otelgin.Middleware("your-app-name")) // Your routes, app's logic, and server start up // ... } ``` </CodeGroup> ## Reporting request parameters By default, the Gin instrumentation does not report any incoming request parameters, like query strings and JSON body contents. To report these values to AppSignal, add a middleware to your Gin-gonic stack as follows: <CodeGroup> ```go Go theme={null} import ( "bytes" "encoding/json" "context" "io/ioutil" "net/url" "github.com/gin-gonic/gin" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" ) func recordParameters(c *gin.Context) { span := trace.SpanFromContext(c.Request.Context()) // Query parameters requestQueryParameters := c.Request.URL.Query() attributeQueryParameters := make(map[string]any) for k, v := range requestQueryParameters { attributeQueryParameters[k] = v } if len(attributeQueryParameters) > 0 { serializedQueryParams, err := json.Marshal(attributeQueryParameters) if err == nil { span.SetAttributes(attribute.String("appsignal.request.query_parameters", string(serializedQueryParams))) } } // Request body payload var serializedBodyPayload string var payload map[string]interface{} requestBodyPayload, err := ioutil.ReadAll(c.Request.Body) if err != nil { c.Next() return } c.Request.Body = ioutil.NopCloser(bytes.NewBuffer(requestBodyPayload)) contentType := c.GetHeader("Content-Type") if contentType == "application/json" { serializedBodyPayload = string(requestBodyPayload) } else if contentType == "application/x-www-form-urlencoded" { // Parse form-urlencoded body values, err := url.ParseQuery(string(requestBodyPayload)) if err != nil { c.Next() return } // Convert form values to a JSON-compatible map payload = make(map[string]interface{}) for key, val := range values { if len(val) == 1 { payload[key] = val[0] } else { payload[key] = val } } json, _ := json.Marshal(payload) serializedBodyPayload = string(json) } else { c.Next() return } if len(serializedBodyPayload) > 0 { span.SetAttributes(attribute.String("appsignal.request.payload", serializedBodyPayload)) } c.Next() } func main() { // Init OpenTelemetry cleanup := initOpenTelemetry() defer cleanup() r := gin.New() r.Use(otelgin.Middleware("opentelemetry-go-gin")) // After the OpenTelemetry middleware, but before your other middlewares: r.Use(recordParameters) // Other middlewares and router handlers go here... } ``` </CodeGroup> # Gorilla Mux Instrumentation Source: https://docs.appsignal.com/go/instrumentations/gorilla-mux [Gorilla Mux](https://github.com/gorilla/mux) is a popular request router and dispatcher for the Go language. <Tip> This project was deprecated in December 2022 and is no longer supported, however, we are aware that this is a popular tool among the Go community, and it'll take a while for users to migrate their apps to new tool. That's why we're providing support for Gorilla Mux apps, so you get valuable information from your services until you find a suitable replacement. </Tip> ## Setup To instrument your Gorilla Mux application, you'll need to import the OpenTelemetry official instrumentation package: <CodeGroup> ```go Go theme={null} import "go.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmux" ``` </CodeGroup> The Gorilla Mux instrumentation is packaged as a router middleware, as you can see in the example below, the tracer initialization is called before anything as described in more detail in the [Go Configuration](/go/configuration) section. Adding `otelmux.Middleware()` to your app router is all that you need to get all your requests instrumented. <CodeGroup> ```go Go theme={null} func main() { cleanup := initOpenTelemetry() defer cleanup() router := mux.NewRouter().StrictSlash(true) // This middleware must be added before any middlewares or routes router.Use(otelmux.Middleware("your-app-name")) // Your routes, app's logic, and server start up // ... } ``` </CodeGroup> ## Reporting request parameters By default, the Gorilla instrumentation does not report any incoming request parameters, like query strings and JSON body contents. To report these values to AppSignal, add a middleware to your Gorilla stack as follows: <CodeGroup> ```go Go theme={null} import ( "bytes" "encoding/json" "io/ioutil" "net/http" "net/url" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" ) func recordParameters(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { span := trace.SpanFromContext(r.Context()) // Query parameters requestQueryParameters := r.URL.Query() attributeQueryParameters := make(map[string]any) for k, v := range requestQueryParameters { attributeQueryParameters[k] = v } if len(attributeQueryParameters) > 0 { serializedQueryParams, err := json.Marshal(attributeQueryParameters) if err == nil { span.SetAttributes(attribute.String("appsignal.request.query_parameters", string(serializedQueryParams))) } } // Request body payload var serializedBodyPayload string var payload map[string]interface{} requestBodyPayload, err := ioutil.ReadAll(r.Body) if err != nil { next.ServeHTTP(w, r) return } r.Body = ioutil.NopCloser(bytes.NewBuffer(requestBodyPayload)) contentType := r.Header.Get("Content-Type") if contentType == "application/json" { serializedBodyPayload = string(requestBodyPayload) } else if contentType == "application/x-www-form-urlencoded" { // Parse form-urlencoded body values, err := url.ParseQuery(string(requestBodyPayload)) if err != nil { next.ServeHTTP(w, r) return } // Convert form values to a JSON-compatible map payload = make(map[string]interface{}) for key, val := range values { if len(val) == 1 { payload[key] = val[0] } else { payload[key] = val } } json, _ := json.Marshal(payload) serializedBodyPayload = string(json) } else { next.ServeHTTP(w, r) return } if len(serializedBodyPayload) > 0 { span.SetAttributes(attribute.String("appsignal.request.payload", serializedBodyPayload)) } next.ServeHTTP(w, r) }) } func main() { // Init OpenTelemetry cleanup := initOpenTelemetry() defer cleanup() router := mux.NewRouter().StrictSlash(true) router.Use(otelmux.Middleware("opentelemetry-go-gorillamux")) // After the OpenTelemetry middleware, but before your other middlewares: router.Use(recordParameters) // Other middlewares and router handlers go here... } ``` </CodeGroup> # MongoDB instrumentation Source: https://docs.appsignal.com/go/instrumentations/mongo ## Setup To instrument your MongoDB usage, you'll need to import the OpenTelemetry official instrumentation package: <CodeGroup> ```go Go theme={null} import "go.opentelemetry.io/contrib/instrumentation/go.mongodb.org/mongo-driver/mongo/otelmongo" ``` </CodeGroup> Before initializing your MongoDB connection, add the `otelmongo.NewMonitor()` as a monitor in the connection options as shown in the example below. <CodeGroup> ```go Go theme={null} opts := options.Client() opts.Monitor = otelmongo.NewMonitor() opts.ApplyURI("mongodb://your.mongo.host:27017") client, err := mongo.Connect(ctx, opts) if err != nil { panic(err) } ``` </CodeGroup> <Warning> At this time the Mongo instrumentation reports all queries in an unsanitized fashion. This means that any PII data is sent to AppSignal, like email addresses and passwords. This will be configurable in a future version of the Mongo instrumentation. </Warning> # Go-Redis Instrumentation Source: https://docs.appsignal.com/go/instrumentations/redis <Warning> The Redis instrumentation currently reports all queries in an unsanitized fashion. This means that any **Personal Identifiable Information (PII)** data those queries contain, like email addresses and passwords, is sent to AppSignal. This will be configurable in a future version of the Redis instrumentation. <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> ## Setup To instrument your Go-Redis code, you'll need to import the OpenTelemetry official instrumentation package: <CodeGroup> ```go Go theme={null} import "github.com/go-redis/redis/extra/redisotel/v9" ``` </CodeGroup> After initializing your Redis client, instrument tracing and metrics as in the example below. <CodeGroup> ```go Go theme={null} rdb := redis.NewClient(&redis.Options{ Addr: "0.0.0.0:6379", }) if err := redisotel.InstrumentTracing(rdb); err != nil { panic(err) } ``` </CodeGroup> # SQL Instrumentation Source: https://docs.appsignal.com/go/instrumentations/sql ## Setup To instrument your SQL usage, you'll need to import the OpenTelemetry official instrumentation packages: <CodeGroup> ```go Go theme={null} import( "github.com/XSAM/otelsql" semconv "go.opentelemetry.io/otel/semconv/v1.4.0" ) ``` </CodeGroup> Your DB connection must be opened using the `otelsql` package, it's also important to query the database using the `QueryContext` function to pass the current context, that way, the spans will be properly nested and structured. The example below shows how to instrument queries to a MySQL database in a web request context. For more information about usage and SQL drivers support, take a look at the [package repository](https://github.com/XSAM/otelsql). <CodeGroup> ```go Go theme={null} func mysqlQuery(w http.ResponseWriter, r *http.Request) { ctx := r.Context() db, err := otelsql.Open( "mysql", "root:password@tcp(0.0.0.0:3306)/mydb", otelsql.WithAttributes(semconv.DBSystemMySQL), ) if err != nil { panic(err) } defer db.Close() rows, err := db.QueryContext(ctx, "select * from mysql.user") if err != nil { panic(err) } defer rows.Close() } ``` </CodeGroup> # AppSignal guides Source: https://docs.appsignal.com/guides Welcome to the AppSignal Guides! Here we'll guide you through every step you need to take to integrate AppSignal with your application successfully. Our guides were written with you in mind, covering everything from adding a new application to finding slow queries. Don't worry if you get lost. Our [Support Page](/support) will help you get back on track. ## Contents * New to AppSignal? We recommend following our [Getting Started Guides](#getting-started-guides) * Exploring more features? Read up on our [Feature Guides](#feature-guides) * Need help managing your application? Check out our [Application Management Guides](#application-management-guides) ## Getting Started Guides AppSignal wasn't built in a day, but it can be installed in minutes. In these guides, we'll help you get set up with your AppSignal Account, show you how to install AppSignal in your application, and learn how to use it to get the most out of your application's metrics. <Tip> In many of these guides you'll be interacting with AppSignal and your applications codebase, so before starting boot up your favourite text editor and grab a cup of something refreshing to drink β˜•οΈ </Tip> 1. [Add a New Application](/guides/new-application) 2. [Configuring Applications](/guides/configuration) 3. [Reporting Deploys to Track Improvements](/guides/deploy-markers) 4. [Grouping Parts of Your Application With Namespaces](/guides/namespaces) 5. [Grouping Errors and Performance Traces With Actions](/guides/actions) 6. [Add Tags to Error and Performance Samples](/guides/tagging) 7. [Customize the Data Added to Error and Performance Samples](/guides/custom-data) 8. Customize which parameters, session data, headers and more are collected by AppSignal integrations: [Filtering App Data](/guides/filter-data) 9. [Add additional OpenTelemetry Instrumentation](/guides/instrumentation/additional-opentelemetry-instrumentation) ## Feature Guides * [Find Slow Database Queries](/guides/slow-queries) * [Find Slow HTTP Requests](/guides/slow-requests) * [Link Traces with Logs](/guides/linking-traces-with-logs) ## Application Management Guides * [Migrating Applications Between Organizations](/guides/application/migrating-applications) * [Removing an Application](/guides/application/deleting-applications) * [Running Multiple Applications on One Host](/guides/application/multiple-applications-on-one-host) # Grouping with Action Names Source: https://docs.appsignal.com/guides/actions When AppSignal receives data from your application, traces/transactions are grouped by their [namespace](/guides/namespaces) and action name combination. By default, these action names are automatically determined based on your framework (e.g., `Controller#action_name`, `BackgroundWorker#perform`, etc.). When the automatically determined action name is not good enough, you can customize the action name. This guide explains how to customize action names in different language integrations. <Warning> Actions names are not meant to be unique! Do not use variables to customize the action names, as this will create a new incident per occurrence. This makes the incident overview difficult to use and prevents proper grouping and trend analysis. **Always use static strings** for action names. Never interpolate variables, user input, or dynamic data into action names. </Warning> ## Why Customize Action Names? * **Improved clarity**: Provide more descriptive names for complex operations. * **Customized grouping**: Control how application data is organized in the AppSignal. ## When Automatic Action Names Fall Short Here are some examples where automatically generated action names may not be good enough: 1. **Catch-all routes**: In applications that use catch-all routes or dynamic routing (like `/api/:entity/:action`), the default action name might be something generic like `ApiController#dispatch`. 2. **Multi-purpose tasks**: Background workers and scripts that handle different types of work based on parameters that would all be grouped under the same action name (e.g., `GenericWorker#perform`). 3. **GraphQL resolvers**: These might all be grouped under a single action name (e.g. `POST /graphql`) despite handling many different types of operations. ## Customizing Actions Per Language * [Ruby](#ruby) * [Elixir](#elixir) * [Python](#python) * [Node.js](#nodejs) * [Front-end JavaScript](#front-end-javascript) * [Go](#go) * [Java](#java) * [PHP](#php) ### Ruby In Ruby applications, you can use the `Appsignal.set_action` helper to customize the action name: <CodeGroup> ```ruby Ruby theme={null} # In a Rails controller class PaymentsController < ApplicationController def process_payment provider = params[:payment][:provider] # GOOD: Change the action name from "PaymentsController#process_payment" # to something more specific about the operation if provider == "creditcard" Appsignal.set_action("PaymentsController#process_payment (creditcard)") end # BAD: Don't use a dynamic value, it creates too many action names # Appsignal.set_action("PaymentsController#process_#{provider}") # Rest of your code end end ``` </CodeGroup> For background jobs, tasks and scripts, you can set the action name in the same way with the `Appsignal.set_action` helper. It's also possible to configure the action name when creating a transaction using the [`Appsignal.monitor`](https://rubydoc.info/gems/appsignal/Appsignal/Helpers/Instrumentation#monitor-instance_method) helper. It accepts the action name as a keyword argument. <CodeGroup> ```ruby Ruby theme={null} # When creating a new transaction Appsignal.monitor(action: "script/custom_script") do # Your code to instrument end ``` </CodeGroup> ### Elixir In Elixir applications, you can use the `Appsignal.Span.set_name/2` function to customize the action name on the **root span**: <CodeGroup> ```elixir Elixir theme={null} # In a Phoenix controller defmodule MyAppWeb.PaymentController do use MyAppWeb, :controller def process(conn, params) do # GOOD: Set a custom static action name based on payment type payment_type = Map.get(params, "type", "unknown") if payment_type == "creditcard" do Appsignal.Span.set_name( Appsignal.Tracer.root_span(), "PaymentController#process_payment (creditcard)" ) end # BAD: Don't use a dynamic value, it creates too many action names # Appsignal.Span.set_name( # Appsignal.Tracer.root_span(), # "PaymentController#process_#{payment_type}" # ) # Rest of your code render(conn, "success.html") end end ``` </CodeGroup> For background jobs, tasks and scripts, you can set the action name in the same way with the `Appsignal.Span.set_name/2` function. ### Node.js In Node.js applications, you can use the `setRootName` helper from the AppSignal package to customize action names: <CodeGroup> ```javascript Node.js theme={null} import { setRootName } from "@appsignal/nodejs"; // In an Express.js route handler app.post("/payments", (req, res) => { const paymentType = req.body.type || "unknown"; // GOOD: Set a custom action name based on payment type if (paymentType === "creditcard") { setRootName("PaymentsController#process_payment (creditcard)"); } // BAD: Don't use a dynamic value, it creates too many action names // setRootName(`PaymentsController#process_${paymentType}`); // Rest of your code res.send("Payment processed"); }); ``` </CodeGroup> For background jobs, tasks and scripts, you can set the action name in the same way with the `setRootName` helper. ### Python In Python applications, you can use the `set_root_name` helper from the AppSignal package to customize action names: <CodeGroup> ```python Python theme={null} from appsignal import set_root_name # In a Django view def process_payment(request): payment_type = request.POST.get('type', 'unknown') # GOOD: Set a custom action name based on payment type if payment_type == "creditcard": set_root_name("PaymentsView#process_payment (creditcard)") # BAD: Don't use a dynamic value, it creates too many action names # set_root_name(f"PaymentsView#process_{payment_type}") # Rest of your code return HttpResponse("Payment processed") ``` </CodeGroup> For background jobs, tasks and scripts, you can set the action name in the same way with the `set_root_name` helper. ### Front-end JavaScript In Front-end JavaScript applications, you can use the `setAction` helper from the AppSignal package to customize action names: <CodeGroup> ```javascript JavaScript theme={null} const span = appsignal.createSpan((span) => { const formType = getFormType(); // GOOD: Set a custom action name based on form type if (formType === "checkout") { span.setAction("CheckoutPage#submit_form (checkout)"); } // BAD: Don't use a dynamic value, it creates too many action names // span.setAction(`CheckoutPage#submit_${formType}_form`); // Rest of your code }); ``` </CodeGroup> Alternatively, you can update an existing span's action name: <CodeGroup> ```javascript JavaScript theme={null} // Get the current active span const span = appsignal.getActiveSpan(); function handlePaymentMethodSelection(method) { // GOOD: Set a custom action name based on payment method if (method === "creditcard") { span.setAction("PaymentForm#select_method (creditcard)"); } // BAD: Don't do this - using a variable creates too many action names // span.setAction(`PaymentForm#select_${method}`); // Rest of your code } ``` </CodeGroup> ### Go In Go applications, AppSignal works with OpenTelemetry, which uses spans to track metadata, such as the action name. On any span in the trace, set an `appsignal.action_name` attribute with a String value to customize the action name: <CodeGroup> ```go Go theme={null} package main import ( "context" "net/http" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" ) func processPaymentHandler(w http.ResponseWriter, r *http.Request) { ctx := r.Context() span := trace.SpanFromContext(ctx) paymentType := r.FormValue("type") // GOOD: Set a custom action name based on payment type if paymentType == "creditcard" { span.SetAttributes(attribute.String("appsignal.action_name", "PaymentHandler#process_payment (creditcard)")) } // BAD: Don't use a dynamic value, it creates too many action names // span.SetAttributes(attribute.String("appsignal.action_name", fmt.Sprintf("PaymentHandler#process_%s", paymentType))) // Rest of your code w.WriteHeader(http.StatusOK) w.Write([]byte("Payment processed")) } ``` </CodeGroup> For background jobs, tasks and scripts, you can set the action name in the same way by setting the `appsignal.action_name` attribute on the active span. ### Java In Java applications, AppSignal works with OpenTelemetry, which uses spans to track metadata, such as the action name. On any span in the trace, set an `appsignal.action_name` attribute with a String value to customize the action name: <CodeGroup> ```java Java theme={null} import io.opentelemetry.api.trace.Span; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController public class PaymentController { @PostMapping("/payments") public String processPayment(@RequestParam String type) { Span span = Span.current(); // GOOD: Set a custom action name based on payment type if ("creditcard".equals(type)) { span.setAttribute("appsignal.action_name", "PaymentController#processPayment (creditcard)"); } // BAD: Don't use a dynamic value, it creates too many action names // span.setAttribute("appsignal.action_name", "PaymentController#process_" + type); // Rest of your code return "Payment processed"; } } ``` </CodeGroup> For background jobs, tasks and scripts, you can set the action name in the same way by setting the `appsignal.action_name` attribute on the active span. ### PHP In PHP applications, you can use the `Appsignal::setAction()` helper method from the AppSignal package to customize action names: <CodeGroup> ```php PHP theme={null} <?php use Appsignal\Appsignal; class PaymentController { public function processPayment() { $paymentType = $_POST['type'] ?? 'unknown'; // GOOD: Set a custom action name based on payment type if ($paymentType === 'creditcard') { Appsignal::setAction('PaymentController::processPayment (creditcard)'); } // BAD: Don't use a dynamic value, it creates too many action names // Appsignal::setAction("PaymentController::process_{$paymentType}"); // Rest of your code return 'Payment processed'; } } ``` </CodeGroup> For background jobs, tasks and scripts, you can set the action name in the same way by setting the `appsignal.action_name` attribute on the active span. ## Best Practices When customizing action names, follow these guidelines: 1. **Be consistent**: Use a consistent naming pattern across your application. 2. **Be specific**: Include relevant information that helps identify the operation. 3. **Avoid high cardinality**: Don't include unique IDs or values that would create unique action names per execution. 4. **Use static strings**: Never interpolate variables or dynamic data into action names. 5. **Follow the codebase naming**: Use naming patterns like `Controller#action` that match your application structure so the location in the code can be found. 6. **Use tags or metadata instead**: For tracking variable information like payment providers or user types, use [tags](/guides/tagging) and [metadata](/guides/custom-data) rather than incorporating them into action names. ## How to Handle Different Operations with the Same Action Name Instead of creating dynamic action names, use a combination of: 1. **Static action names**: Use descriptive but static action names. 2. **Tags**: [Add tags](/guides/tagging) with the variable information (e.g., `provider: stripe`, `operation_type: refund`). 3. **Custom attributes**: [Add additional metadata](/guides/custom-data) to the trace/transaction. Example: <CodeGroup> ```ruby Ruby theme={null} # Instead of this: # Appsignal.set_action("PaymentController#process_#{provider}") # Do this: Appsignal.set_action("PaymentController#process_payment") Appsignal.add_tags( provider: provider, operation: operation ) ``` </CodeGroup> This approach allows you to: * Group related operations under a single action name. * Filter and search based on tags. * Maintain a clean incident overview. ## Deploy After you've implemented custom action names, deploy your application. New traces/transactions will use your custom action names in the AppSignal dashboards. <Tip> Historical data will still use the original action names. Only newly reported actions will use the custom names you've defined. </Tip> Are your custom action names not appearing correctly? Don't hesitate to [contact our support team](mailto:support@appsignal.com) for help! ## Further Reading * [Grouping with Namespaces](/guides/namespaces) * [Add Tags](/guides/tagging) * [Add Metadata](/guides/custom-data) * [Ignore Specific Actions](/guides/filter-data/ignore-actions) # Deleting Applications Source: https://docs.appsignal.com/guides/application/deleting-applications An application (app) in AppSignal is defined as the combination of the application name and environment, e.g. "My app - production". You can only remove/delete one environment at a time through the UI. <Tip> Apps are automatically recreated when our servers receive data from your app. To remove an app, first make sure AppSignal is completely uninstalled from your applications before removing it on AppSignal.com </Tip> Please follow the uninstall guide for the programming language of your application(s) listed below: * [Ruby gem uninstall guide](/ruby/installation/#uninstall) * [Elixir package uninstall guide](/elixir/installation#uninstall) * [JavaScript for Front-end package uninstall guide](/front-end/installation#uninstall) When your app is no longer pushing data to the AppSignal servers, remove your app on the [App Settings page](https://appsignal.com/redirect-to/app?to=edit) for your app on AppSignal.com. * Visit the [App Settings](https://appsignal.com/redirect-to/app?to=edit) page. * Scroll down to the bottom of the page. * In the "Delete \<app name>" section, click on the "delete \<app name>" button and confirm the confirmation prompt. Your app is now scheduled for deletion. It and all its data will be removed from your organization and our servers. This may take a few minutes, after which it will disappear from your apps list. ## See also * [Application topic](/application/) * [Guides index](/guides/) # Migrating applications between organizations Source: https://docs.appsignal.com/guides/application/migrating-applications While it's not possible to directly transfer apps between organizations in the AppSignal.com interface, they can be moved with some configuration changes. We do not have an option for migrating on the AppSignal.com app because of these configuration changes. The organization-level Push API key needs to be changed in an app to migrate an app. To migrate an app you can choose to [either keep](#migration-with-app-data-and-history), or [not keep](#migration-without-keeping-app-data-and-history) the app's data and history: errors, performance measurements, metrics, etc. ## Migration without keeping app data and history If you do not want to keep the app's data we recommend to update your application config with the new organization's Push API key. After a deploy, a new app with the same name and environment will appear under the new organisation. Once the new app reports data, you can [remove the old app][remove guide] in the other organization. ## Migration with app data and history If you like to have the history of the application as well, you will then need to [contact us][contact] so we can help you in this process by going through the following steps. * Step 1 * First you'd need to update your Push API key for the app you'd like to move to an app-specific key, instead of an organization-specific key. This ensures data that's being sent during the move will end up under the correct app. You can find the app-specific key in the [app settings section][app settings], the second key listed there. * Step 2 * Once you [inform us][contact] that you have taken care of the step above, we will then move the application data to the new organization. This process can take a couple of hours, depending on the amount of samples. * Step 3 * Once the data migration is complete, we move the app itself to the new organization. * Note that we can't migrate everything, as some things are organization specific, such as certain integration such as Jira/GitHub or notifiers such as Slack. * Step 4 * Deploy the app again with the new organization-specific API key (from the new organization) as found in the [app settings section][app settings], first key listed there. * The migration is now complete. ## See also * [Application topic](/application/) * [Guides index](/guides/) [contact]: mailto:support@appsignal.com [app settings]: https://appsignal.com/redirect-to/app?to=info [remove guide]: /guides/application/deleting-applications.html # Running multiple applications on one host Source: https://docs.appsignal.com/guides/application/multiple-applications-on-one-host ## The problem When running multiple applications on one host some odd behavior may occur. One common problem we've seen is that Applications start reporting under different names and/or environments. Such as an application switching between the staging and production environment after a deploy or restart of an application process or worker. ## Background The AppSignal agent starts using an application config. It uses this configuration to send the data to the AppSignal servers to report it as that app on AppSignal.com. By default AppSignal is configured to assume one application runs on one host. If you run more than one application on a host, some configuration is required to avoid sharing the AppSignal working directory between multiple applications. This way multiple AppSignal agents can run at the same time with a different application config. <Tip> Read more about the AppSignal [working directory](/appsignal/how-appsignal-operates#working-directory). </Tip> ## Configuration To allow AppSignal to be used for multiple applications on one host we need to set the "working directory path" configuration option. Using this configuration option, we need to set a unique working directory path per application for AppSignal to store its (temporary) files. This way the AppSignal agent will not share the working directory between multiple applications. ### Ruby To set the working directory path in the Ruby integration, add the following to your AppSignal configuration file. The [`working_directory_path`][ruby working_directory_path] value is a path to an existing directory on your host system. <CodeGroup> ```ruby Ruby theme={null} Appsignal.configure do |config| config.working_directory_path = "/tmp/project_1/" end ``` ```yaml YAML theme={null} production: working_directory_path: "/tmp/project_1/" ``` </CodeGroup> #### Read more * [Ruby integration `working_directory_path` config option details][ruby working_directory_path] [ruby working_directory_path]: /ruby/configuration/options.html#option-working_directory_path ### Elixir To set the working directory path in the Elixir integration, add the following to your AppSignal configuration file. The [`working_directory_path`][elixir working_directory_path] value is a path to an existing directory on your host system. <CodeGroup> ```elixir Elixir theme={null} config :appsignal, :config, working_directory_path: "/tmp/project_1/" ``` </CodeGroup> #### Read more * [Elixir integration `working_directory_path` config option details][elixir working_directory_path] [elixir working_directory_path]: /elixir/configuration/options.html#option-working_directory_path ### Node.js To set the working directory path in the Node.js integration, add the following to your AppSignal configuration file. The [`workingDirectoryPath`][nodejs working_directory_path] value is a path to an existing directory on your host system. <CodeGroup> ```javascript Node.js theme={null} const { Appsignal } = require("@appsignal/nodejs"); const appsignal = new Appsignal({ // Other config workingDirectoryPath: "/tmp/project_1", }); module.exports = { appsignal }; ``` </CodeGroup> #### Read more * [Node.js integration `workingDirectoryPath` config option details][nodejs working_directory_path] [nodejs working_directory_path]: /nodejs/3.x/configuration/options.html#option-workingdirectorypath ### Python For the Python integration, two config options need to be changed. The first is the `working_directory_path` config option, and the other the `opentelemetry_port` config option. To set these config options in the Python integration, add the following to your AppSignal configuration file. The [`opentelemetry_port`][python opentelemetry_port] value is a number of a port that is available and the [`working_directory_path`][python working_directory_path] value is a path to an existing directory on your host system. These should be unique values per app. <CodeGroup> ```python Python theme={null} from appsignal import Appsignal appsignal = Appsignal( # Other config opentelemetry_port: 9001, working_directory_path: "/tmp/project_1" ) ``` </CodeGroup> #### Read more * [Python integration `opentelemetry_port` config option details][python opentelemetry_port] * [Python integration `working_directory_path` config option details][python working_directory_path] [python opentelemetry_port]: /python/configuration/options.html#option-opentelemetry_port [python working_directory_path]: /python/configuration/options.html#option-working_directory_path ### Front-end JavaScript No working directory can be configured for Front-end JavaScript applications as it does not rely on the AppSignal agent process. If data is reported for the wrong application, please make sure the application is using the correct [Push API key](/appsignal/terminology#push-api-key) ## See also * [Application topic](/application/) * [Guides index](/guides/) # Configuring Applications Source: https://docs.appsignal.com/guides/configuration Welcome to our Configuration Guide. This guide will teach you how to add and modify configurations for your AppSignal integration. <Tip> Read more information about AppSignal integration configuration in your app in our [configuration section][config topic]. </Tip> ## Choose a Configuration Option This guide will walk you through the steps necessary to configure your application to best suit your needs. There are, of course, multiple configuration options for your application, but since the implementation method for all options is identical, in this guide, we'll focus on the following configurations: We'll be using the `log_level` option as an example for [Ruby](/ruby/configuration/options#option-log_level), [Elixir](/elixir/configuration/options#option-log_level), [Node.js](/nodejs/3.x/configuration/options#option-loglevel) and [Python](/python/configuration/options#option-log_level) applications. We'll use the `namespace` option as an example for [Front-end JavaScript applications](/front-end/configuration). ## Configuration Methods There are multiple ways to configure your AppSignal integration, and integrations can vary depending on your application's language, but they all have the following configuration methods: * [File Based Configuration:](#file-based-configuration) <br />A config file where the AppSignal integration reads the AppSignal configuration. * [System Environment Variable Configuration:][env] <br /> Environment variables are set on the host system (server) on the parent process that starts your application. <br /> **Note**: This method is not available for front-end JavaScript. ## File Based Configuration File-based configuration is the easiest way to configure your integration. Some integrations create a config file during the installation of AppSignal in the app. In these config files, you can uniquely configure one or multiple application environments. <Tip> Make sure to use the "Config file key" value from the config options table as the config key. This key is either a snake\_cased (Ruby, Elixir, Python) or camelCased string (Node, Front-End JavaScript). </Tip> Config options for: * [Ruby](/ruby/configuration/options) * [Elixir](/elixir/configuration/options) * [Node.js](/nodejs/3.x/configuration/options) * [Python](/python/configuration/options) * [Front-end Javascript](/front-end/configuration/) * [Go](/go/configuration/options) <Warning> Make sure to not check-in any sensitive configuration values, such as the Push API key into a source-control management system like Git, unless they are encrypted. </Warning> ### Ruby When using the Ruby integration gem, it will create the `config/appsignal.yml` in your applications root folder, with basic configuration settings upon installation. If your application reports data to AppSignal without an `appsignal.yml` file, your application is most likely using [system environment variables][env]. <Tip> The `config/appsignal.yml` file is a YAML (Yet Another Markup Language) file. and is interpreted as an ERB (Embeded Ruby) template, Please see the [Ruby Configuration][ruby config] documentation for more details on how the YAML configuration works. </Tip> In the below example config file, two environments are defined, `development` and `production` - each has environment specific configuration options nested under them. Everything defined and nested within `default` applies to all environments, as long as default is included in the environment mapping. We want to set the log\_level to debug exclusively in our `development` environment; to do this, we've added `log_level: "debug"` in the development environment configuration (line 10). <CodeGroup> ```yaml YAML theme={null} # Example: config/appsignal.yml default: &defaults # Shared configuration options for all environments active: true name: "My awesome app" push_api_key: "<YOUR PUSH API KEY>" development: # Development environment <<: *defaults log_level: "debug" # This enables debug mode for only the development environment production: # Production environment <<: *defaults ``` </CodeGroup> Remember, everything nested within `default` is applied to all environments, so to set the log\_level to debug in all environments, we can instead nest the configuration under default, as done in line 6 of the below example code: <CodeGroup> ```yaml YAML theme={null} # Example: config/appsignal.yml default: &defaults active: true name: "My awesome app" push_api_key: "<YOUR PUSH API KEY>" log_level: "debug" # This enables debug mode for all environments # Other AppSignal config... development: # Development environment <<: *defaults # Other AppSignal config... production: # Production environment <<: *defaults # Other AppSignal config... ``` </CodeGroup> Great, now you've learned how to configure AppSignal in your Ruby application! #### Read More: * [Ruby Integration Configuration Topic][ruby config] * [Ruby Integration Configuration Load Order Details](/ruby/configuration/load-order) ### Elixir Upon installation, the Elixir integration creates a `config/appsignal.exs` (default location) file with basic configurations. If this file is not present but your application reports data to AppSignal, check any of the other `.exs` files in the `config/` directory of your Elixir app. If no AppSignal configuration is present in any of the files, your application is likely using [system environment variables][env] as a configuration method instead. To add a configuration option and have it apply to all your application's environments, add the config option to the `config/appsignal.exs` file, like on line 7 of the example below: <CodeGroup> ```elixir Elixir theme={null} # Example: config/config.exs config :appsignal, :config, active: true, name: "My awesome app", push_api_key: "<YOUR PUSH API KEY>", env: Mix.env, log_level: "debug" # This sets the log_level to debug for all environments ``` </CodeGroup> To only apply the config option to a single environment, add the AppSignal configuration to the environment's config file, located in the `config/` directory. In the example below, the log\_level option has been added on line 3 of the development (or "dev") environment: <CodeGroup> ```elixir Elixir theme={null} # Example: config/dev.exs config :appsignal, :config, log_level: "debug" # This only sets the log_level to debug for the "dev" environment ``` </CodeGroup> Great, now you've learned how to configure AppSignal in your Elixir application! #### Read More * [Elixir Integration Configuration Topic](/elixir/configuration/) * [Elixir Integration Configuration Load Order Details](/elixir/configuration/load-order) ### Node.js After installation, you need to create an AppSignal config file to configure your application. If no file with AppSignal configuration is present, it is most likely using [system environment variables][env] as a configuration method instead. To configure AppSignal for Node.js apps, we recommend creating an `appsignal.js` file with the AppSignal config in your application's root or `src` directory. Then require/import it from the app's code before any other packages are required or imported. In the example below, there is an `appsignal.js` file in the root of the app directory. In this file, we'll add the `logLevel` config option. <CodeGroup> ```javascript Node.js theme={null} // appsignal.js const { Appsignal } = require("@appsignal/nodejs"); const appsignal = new Appsignal({ active: true, name: "<YOUR APPLICATION NAME>", pushApiKey: "<YOUR API KEY>", logLevel: "debug", // Sets logLevel to debug for the Node.js environment }); module.exports = { appsignal }; ``` </CodeGroup> The config in the example above applies to the environment Node.js is running in (`NODE_ENV`, defaults to "development"). In Node.js there are many ways to create environment-specific configurations for AppSignal. If you are unsure how to do this within your own application, one method we recommend is using conditionals in your `appsignal.js`, such as in the example below where we specify debug for the production environment. 1. On line 4 - we only activate the AppSignal integration if the environment is production. 2. On line 8 - as in our previous code example we set the `logLevel` to `debug` <CodeGroup> ```javascript Node.js theme={null} // appsignal.js const appsignal = new Appsignal({ active: process.env.NODE_ENV === "production" name: "<YOUR APPLICATION NAME>", pushApiKey: "<YOUR API KEY>", logLevel: "debug" // Sets logLevel to debug for the Node.js environment }); ``` </CodeGroup> Once your configuration is completed, you need to require `appsignal.js` at the very top of your app's main file. Your application's main file name may vary depending on how your application is structured. It is the file you use to start your Node application and is usually called `index.js` or `app.js`. Ensure AppSignal is required at the very top of the file like in the example below: <CodeGroup> ```javascript Node.js theme={null} // index.js // Place this at the top const { appsignal } = require("./appsignal"); // Update to the location used in the previous step // Place your app code below this ``` </CodeGroup> Great, now you've learned how to configure AppSignal in your Node.js application! #### Read More * [Node.js Integration Configuration][nodejs config] * [Node.js Integration Configuration Load Order](/nodejs/3.x/configuration/load-order) ### Python When using the Python integration installer, it will create the `__appsignal__.py` in your applications root folder, with basic configuration settings. Your application can also be configured using [system environment variables][env]. To add a configuration option and have it apply to your development application environment, add the config option to the `__appsignal__.py` file, like in the example below. <CodeGroup> ```python Python theme={null} # __appsignal__.py from appsignal import Appsignal appsignal = Appsignal( active=True, name="My awesome app", push_api_key="<YOUR PUSH API KEY>", environment="development", log_level="debug", ) ``` </CodeGroup> To configure AppSignal for Python for another environment, or apply the config to all to environments, configure the `environment` config option in the same way your app determines its environment (development/staging/production). This can be using a system environment variable or some other application specific method. In the example below we'll be using a system environment variable `MY_APP_ENV` to both set the app environment and only activate for the production environment. <CodeGroup> ```python Python theme={null} # __appsignal__.py import os from appsignal import Appsignal app_env = os.environ.get("MY_APP_ENV") appsignal = Appsignal( active=app_env == "production", name="My awesome app", push_api_key="<YOUR PUSH API KEY>", environment=app_env, ) ``` </CodeGroup> If you want some config options to only apply to certain environments, create conditionals to fit your needs. <CodeGroup> ```python Python theme={null} # __appsignal__.py import os from appsignal import Appsignal app_env = os.environ.get("MY_APP_ENV") options = { "active": app_env == "development", "name": "python/django4-celery", "environment": app_env, } if app_env == "development": options["log_level"] = "debug" appsignal = Appsignal(**options) ``` </CodeGroup> Great, now you've learned how to configure AppSignal in your Python application! #### Read More: * [Python Integration Configuration Topic][python config] * [Python Integration Configuration Load Order Details](/python/configuration/load-order) ### Front-end JavaScript To configure AppSignal for front-end JavaScript, we recommend creating an `appsignal.js` file with the AppSignal config in your project's root or `src` directory. Then require or import it from the app's code before any other packages are required or imported. In the example below, there is an `appsignal.js` file in the root of the applications directory. On line 8 we've added the `namespace` config option. <CodeGroup> ```javascript JavaScript theme={null} // appsignal.js import Appsignal from "@appsignal/javascript"; // For ES Module const Appsignal = require("@appsignal/javascript").default; // For CommonJS module const appsignal = new Appsignal({ key: "<YOUR FRONTEND API KEY>", namespace: "frontend", // Configure the AppSignal namespace for front-end errors in this app }); module.exports = { appsignal }; ``` </CodeGroup> Once you're done with your application's config, you need to require `appsignal.js` the very top of your application's main file, like in the example below: <CodeGroup> ```javascript JavaScript theme={null} // index.js // Place this at the top const { appsignal } = require("./appsignal"); // Update to the location used in the previous step // Place your app code below this ``` </CodeGroup> And that's it - you're ready to roll! Follow these simple steps for all future config option modifications. #### Read More * [Front-end JavaScript Integration Configuration](/front-end/configuration/) ## System Environment Variable Configuration <Warning> This configuration method is not available for Front-end JavaScript. </Warning> System environment variables, or "environment variables" for short, are variables that are accessible by processes, and are inherited from the parent process who starts them. Instead of using a [configuration file][file] for configuration, it's possible to configure AppSignal using only environment variables. It is also possible to store config keys that contain sensitive data, such as the Push API key in an environment variable, and use [config files][file] for the rest of the config. This configuration method is compatible with Ruby, Elixir, and Node.js applications. Before moving on to the following example of setting environment variables via a shell, let's explain how environment variables work concerning shells and processes. Environment variables can belong to a process such as a shell or your application. The command `export FOO=BAR`, for example, would set your shell's `FOO` environment variable to equal `BAR`. Environment variables are inherited between processes, so when that shell starts a new process, that process will also have any of the shell's environment variables. When you launch a process in the shell (i.e., npm start) you can also provide more environment variables for only that process by assigning the variables like so: `FOO=BAR npm start` For convenience, you may want to configure your shell to set certain environment variables when it starts, so that any processes started from that shell inherits those environment variables. If you're using the `bash` shell, the commands in the `.bash_profile` file in your home directory are executed when the shell is started. If using `zsh`, which is the default shell in macOS, the `.zshenv` file would be used instead to configure environment variables. In the example file below, we export the environment variables that configure AppSignal's push API key and log level, so that when a new shell is started, the correct environment variables are accessible to your application, allowing it to communicate with AppSignal. Config options set via environment variables apply to all application environments, however some config options are language specific. For example, the config option `instrument_sequel` only exists in the Ruby integration, because Sequel is a Ruby gem, and therefore setting the `APPSIGNAL_INSTRUMENT_SEQUEL` environment variable has no effect for other integrations. <CodeGroup> ```sh Shell theme={null} # Bash shell example export APPSIGNAL_PUSH_API_KEY=<YOUR PUSH API KEY> export APPSIGNAL_LOG_LEVEL=debug # Sets log_level to debug for all environments. ``` </CodeGroup> There are several possible locations for files with environment variables configuration. Please choose the best option that suits your application, and be sure to reload your terminal shell after making any changes to ensure it has access to your updated variables. * `~/.profile` or `~/.bash_profile` - User specific settings. Use this location to configure environment variables per user. * `/etc/profile` - System-wide settings. If multiple users or apps use the same host machine, do not use this location. Platform As A Service (PaaS) hosting providers like Heroku, do not provide a system for directly configuring environment variables in the shell. You can instead use their web interface or CLI to configure these environment variables. <Note> When using system environment variable based configuration, make sure to use the "System environment key" value from the config options table as the config key. This key is always is capitalized\* snake case, like this: `EXAMPLE_OF_A_CONFIG_KEY` <br /> ***Fun Fact:** this is also known as SCREAMING\_SNAKE\_CASE 🐍* </Note> ## Completing The Configuration After changing your AppSignal configuration, your application needs to be restarted or deployed for the configuration changes to be detected by AppSignal. Are configuration changes not being detected? [Get in touch][contact], and we'll help you out! To help us debug your issue quicker, we recommend sending us a [diagnose report](/support/debugging#diagnose) from your application's host. ## Further Reading Read more about configuration in our [Application Configuration][config topic] documentation. [config topic]: /application/configuration.html [contact]: mailto:support@appsignal.com [env]: #system-environment-variable-configuration [file]: #file-based-configuration [nodejs config]: /nodejs/3.x/configuration/ [ruby config]: /ruby/configuration/ [python config]: /python/configuration/ # Data customization Source: https://docs.appsignal.com/guides/custom-data To help you keep an eye on errors and performance issues AppSignal allows you to provide the extra context by adding additional data to requests. ## Request Parameters [Request parameters](/guides/custom-data/request-parameters) are both request query parameters and POST request payloads. AppSignal captures these parameters to help you understand what specific input may have triggered an error or performance issue. ## Request Session Data [Request session data](/guides/custom-data/request-session-data) are values stored in a user's session, such as preferences and state. This data can help debug issues with specific states of a user session. ## Request Headers [Request headers](/guides/custom-data/request-headers) include metadata about the HTTP request, such as the User-Agent, Content-Type, and custom headers. Capturing these can help you debug issues related to browsers, platforms, API versions, etc. ## Function parameters [Function parameters](/guides/custom-data/function-parameters) are the parameters that background jobs or scripts start with. Capturing them can help you debug issues related to the initial context of those scripts. ## Custom Data [Custom data](/guides/custom-data/custom-data) lets you attach any additional information you consider useful that does not fit in any of the other data categories. # Add Custom Data Source: https://docs.appsignal.com/guides/custom-data/custom-data <Compatibility /> You can use custom sample data to set more dynamic values than is possible with [other types of data customization](/guides/custom-data). <Warning> πŸ” Do not send <strong>Personal Identifiable Information (PII)</strong> to AppSignal. Filter PII (e.g., names, emails) and use an ID, hash, or pseudonymized identifier instead. <br /> <br /> Use [Link Templates](https://docs.appsignal.com/application/link-templates) to link them back in your app. </Warning> See the table below for a list of accepted root values per language. Each nested object can contain values that result in valid JSON (strings, integers, floats, booleans, nulls, etc.). | Language | Accepted root values | | ---------- | -------------------- | | Ruby | Arrays, Hashes | | JavaScript | Arrays, Objects | | Elixir | Lists, Maps | | Python | Lists, Maps | | PHP | Arrays, Objects | It is not possible to filter or search on the data set as custom data. It only provides an additional area in the interface to list more metadata. When using custom data for nested objects, you can view the object on the Incident Sample page for both Exception and Performance samples formatted as JSON, like in the example below: <CodeGroup> ```ruby Ruby theme={null} # Call `add_custom_data` multiple times to add more custom data # Hash example Appsignal.add_custom_data( :stroopwaffle => { :caramel => true }, :market => { :type => "outdoors" } ) Appsignal.add_custom_data(:market => { :state => :closed }) Appsignal.add_custom_data(:market => { :state => :open }) # Custom data: # { # :stroopwaffle => { :caramel => true }, # :market => { :state => :open } # } # Array example Appsignal.add_custom_data(["value 1"]) Appsignal.add_custom_data(["value 2"]) # Custom data: ["value 1", "value 2"] # Mixed data type example # The Hash and Array data type cannot be mixed at the root level Appsignal.add_custom_data(:market => :open) Appsignal.add_custom_data(["value 1"]) # Custom data: ["value 1"] ``` ```elixir Elixir theme={null} # Map Appsignal.Span.set_sample_data( Appsignal.Tracer.root_span, "custom_data", %{ stroopwaffle: %{ caramel: true, origin: "market" } } ) # List Appsignal.Span.set_sample_data( Appsignal.Tracer.root_span, "custom_data", [ "value 1", "value 2" ] ) ``` ```javascript Node.js theme={null} import { setCustomData } from "@appsignal/nodejs"; // Object setCustomData({ stroopwaffle: { caramel: true, origin: "market", }, }); // Array setCustomData(["value 1", "value 2"]); ``` ```python Python theme={null} from appsignal import set_custom_data # Map set_custom_data({ "stroopwaffle": { "caramel": true, "origin": "market" } }) # Array set_custom_data(["value 1", "value 2"]) ``` ```php PHP theme={null} <?php use Appsignal\Appsignal; Appsignal::setCustomData([ 'stroopwaffle' => [ 'caramel' => true, 'origin' => 'market', ], ]); ``` </CodeGroup> If the application sets custom data multiple times, the Ruby gem will merge values at the root level. For other integrations, only the last set value is stored. <img alt="custom_data" /> # Add Function Parameters Source: https://docs.appsignal.com/guides/custom-data/function-parameters <Compatibility /> <Compatibility /> PHP and the languages supported through our OpenTelemetry beta can set function parameters. Function parameters are designated for background jobs and scripts, not for storing parameters for each function call in a trace. <Warning> πŸ” Do not send <strong>Personal Identifiable Information (PII)</strong> to AppSignal. Filter PII (e.g., names, emails) and use an ID, hash, or pseudonymized identifier instead. <br /> <br /> Use [Link Templates](https://docs.appsignal.com/application/link-templates) to link them back in your app. </Warning> For security and privacy we recommend [filtering function parameters](/guides/filter-data/filter-function-parameters) before sending them to our servers. See the table below for a list of accepted root values per language. Each nested object can contain values that result in valid JSON (strings, integers, floats, booleans, nulls, etc.). | Language | Accepted root values | | -------- | ---------------------- | | Go | JSON serialized string | | Java | JSON serialized string | | PHP | Arrays, Objects | The below code sample shows how to set custom request parameters: <CodeGroup> ```go Go theme={null} // Additional setup is required to first fetch or create a new span import ( "encoding/json" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" ) params := map[string]interface{}{ "param1": "value1", "param2": "value2", "nested": map[string]interface{}{ "param3": "value3", "param4": "value4", }, } json, _ := json.Marshal(params) span.SetAttributes(attribute.String("appsignal.function.parameters", string(json))) ``` ```java Java theme={null} // Additional setup is required to first fetch or create a new span import io.opentelemetry.api.trace.Span; // We're using the Jackson JSON library // You may need to add it to your project as a dependency import com.fasterxml.jackson.databind.ObjectMapper; import java.util.HashMap; import java.util.Map; Map<String, Object> params = new HashMap<>(); params.put("param1", "value1"); params.put("param2", "value2"); Map<String, String> nested = new HashMap<>(); nested.put("param3", "value3"); nested.put("param4", "value4"); params.put("nested", nested); try { ObjectMapper mapper = new ObjectMapper(); String jsonString = mapper.writeValueAsString(params); Span span = Span.current(); span.setAttribute("appsignal.function.parameters", jsonString); } catch (Exception e) { // Add error handling here } ``` ```php PHP theme={null} <?php use Appsignal\Appsignal; $params = [ 'param1' => 'value1', 'param2' => 'value2', 'nested' => [ 'param3' => 'value3', 'param4' => 'value4', ], ]; Appsignal::setFunctionParams($params); ``` </CodeGroup> For certain languages, additional setup is required. Please follow the instructions for these languages: * [Go](/go/custom-instrumentation) * [Java](/java/custom-instrumentation) ## Limitations If the application sets function parameters multiple times, the latest set value is leading. # Add Request Headers Source: https://docs.appsignal.com/guides/custom-data/request-headers <Compatibility /> By default, the AppSignal integrations track request HTTP headers for web applications in supported libraries. You can set custom request headers on a transaction or span. Modifying the request headers will overwrite the data set by the AppSignal instrumentations. [All request headers are filtered](/guides/filter-data/filter-headers) by our integrations before being sent to our servers. <Warning> πŸ” Do not send <strong>Personal Identifiable Information (PII)</strong> to AppSignal. Filter PII (e.g., names, emails) and use an ID, hash, or pseudonymized identifier instead. <br /> <br /> Use [Link Templates](https://docs.appsignal.com/application/link-templates) to link them back in your app. </Warning> See the table below for a list of accepted value types for request headers. | Language | Accepted header name | Accepted header value | | -------- | -------------------- | --------------------- | | Ruby | String | String | | Elixir | String | String | | Node.js | String | String | | Python | String | String | | Go | String | String, String slice | | Java | String | String, String array | | PHP | String | String, String array | The below code sample shows how to set custom request headers: <CodeGroup> ```ruby Ruby theme={null} # Call `add_headers` multiple times to set more headers Appsignal.add_headers("REQUEST_METHOD" => "GET", "REQUEST_PATH" => "/some-path") Appsignal.add_headers("PATH_INFO" => "/a-path") Appsignal.add_headers("PATH_INFO" => "/some-path") # Headers: # { # "REQUEST_METHOD" => "GET", # "REQUEST_PATH" => "/some-path", # "PATH_INFO" => "/some-path" # } ``` ```elixir Elixir theme={null} Appsignal.Span.set_sample_data( Appsignal.Tracer.root_span, "environment", %{ "request_method" => "GET", "path_info" => "/some-path" } ) ``` ```javascript Node.js theme={null} import { setHeader } from "@appsignal/nodejs"; setHeader("request_method", "GET"); setHeader("path_info", "/some-path"); ``` ```python Python theme={null} from appsignal import set_header set_header("request_method", "GET"); set_header("path_info", "/some-path"); ``` ```go Go theme={null} // Additional setup is required to first fetch or create a new span span.SetAttributes(attribute.StringSlice("http.request.header.content-type", []string{"application/json"})) span.SetAttributes(attribute.StringSlice("http.request.header.custom-header"), []string{"abc", "def"}) ``` ```java Java theme={null} import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.common.AttributeKey; import java.util.Arrays; // Additional setup is required to first fetch or create a new span Span span = Span.current(); // Set single header values span.setAttribute("http.request.header.request-method", "GET"); span.setAttribute("http.request.header.path-info", "/some-path"); span.setAttribute("http.request.header.content-type", "application/json"); // Set header with multiple values (array) span.setAttribute( AttributeKey.stringArrayKey("http.request.header.custom-header"), Arrays.asList("value1", "value2") ); ``` ```php PHP theme={null} <?php use Appsignal\Appsignal; // Set single header values Appsignal::addHeaders([ 'request-method' => 'GET', 'path-info' => '/some-path', 'content-type' => 'application/json', ]); // Set header with multiple values (array) Appsignal::addHeaders([ 'custom-header' => ['value1', 'value2'], ]); ``` </CodeGroup> For certain languages, additional setup is required. Please follow the instructions for these languages: * [Go](/go/custom-instrumentation) * [Java](/java/custom-instrumentation) <img alt="environment" /> ## Limitations Only the last value for a request header is stored if the application sets a request header multiple times. For Elixir, if the helper is called multiple times, only the last set of request headers (environment) is stored. # Add Request Parameters Source: https://docs.appsignal.com/guides/custom-data/request-parameters <Compatibility /> By default, the AppSignal integrations track request parameters for web requests in supported libraries. These include query parameters and the POST request body\*. For background jobs, we store the job arguments in the parameters. <Tip> \*: The AppSignal for PHP package and the languages supported through our [OpenTelemetry beta](/opentelemetry) store the request query parameters and request payload data separately. See the [request payload data](#request-payload-data) section for more information on how to set request payload data separately. </Tip> <Warning> πŸ” Do not send <strong>Personal Identifiable Information (PII)</strong> to AppSignal. Filter PII (e.g., names, emails) and use an ID, hash, or pseudonymized identifier instead. <br /> <br /> Use [Link Templates](https://docs.appsignal.com/application/link-templates) to link them back in your app. </Warning> You can set custom parameters on a transaction or span. Modifying the parameters of a transaction will overwrite the data set by the AppSignal instrumentations. [All parameters are filtered](/guides/filter-data/filter-parameters) by our integrations before being sent to our servers. See the table below for a list of accepted root values per language. Each nested object can contain values that result in valid JSON (strings, integers, floats, booleans, nulls, etc.). | Language | Accepted root values | | ---------- | ---------------------- | | Ruby | Arrays, Hashes | | JavaScript | Arrays, Objects | | Elixir | Lists, Maps | | Python | Lists, Maps | | Go | JSON serialized string | | Java | JSON serialized string | | PHP | Arrays, Objects | The below code sample shows how to set custom request parameters: <CodeGroup> ```ruby Ruby theme={null} # Values are merged at the top level Appsignal.add_params( :post => { :title => "My title", :body => "Post text." } ) Appsignal.add_params(:user => { :login => "some_name" }) Appsignal.add_params(:user => { :id => 123 }) # Parameters: # { # :post => { :title => "My title", :body => "Post text." }, # :user => { :id => 123 } # } ``` ```elixir Elixir theme={null} Appsignal.Span.set_sample_data( Appsignal.Tracer.root_span, "params", %{ post: %{ title: "My new blog post!", body: "Some long blog post text." } } ) ``` ```javascript Node.js theme={null} import { setParams } from "@appsignal/nodejs"; setParams({ post: { title: "My new blog post!", body: "Some long blog post text.", }, }); ``` ```python Python theme={null} from appsignal import set_params set_params({ post: { title: "My new blog post!", body: "Some long blog post text." } }) ``` ```go Go theme={null} // Additional setup is required to first fetch or create a new span import ( "encoding/json" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" ) params := map[string]interface{}{ "param1": "value1", "param2": "value2", "nested": map[string]interface{}{ "param3": "value3", "param4": "value4", }, } json, _ := json.Marshal(params) span.SetAttributes(attribute.String("appsignal.request.query_parameters", string(json))) ``` ```java Java theme={null} // Additional setup is required to first fetch or create a new span import io.opentelemetry.api.trace.Span; // We're using the Jackson JSON library // You may need to add it to your project as a dependency import com.fasterxml.jackson.databind.ObjectMapper; import java.util.HashMap; import java.util.Map; Map<String, Object> queryParams = new HashMap<>(); queryParams.put("param1", "value1"); queryParams.put("param2", "value2"); Map<String, String> nested = new HashMap<>(); nested.put("param3", "value3"); nested.put("param4", "value4"); queryParams.put("nested", nested); try { ObjectMapper mapper = new ObjectMapper(); String jsonString = mapper.writeValueAsString(queryParams); Span span = Span.current(); span.setAttribute("appsignal.request.query_parameters", jsonString); } catch (Exception e) { // Add error handling here } ``` ```php PHP theme={null} <?php use Appsignal\Appsignal; $params = [ 'param1' => 'value1', 'param2' => 'value2', 'nested' => [ 'param3' => 'value3', 'param4' => 'value4', ], ]; Appsignal::setParams($params); ``` </CodeGroup> For certain languages, additional setup is required. Please follow the instructions for these languages: * [Go](/go/custom-instrumentation) * [Java](/java/custom-instrumentation) <img alt="params" /> ## Request payload data The AppSignal for PHP package and languages supported through our [OpenTelemetry beta](/opentelemetry) store the request query parameters and request payload data separately. This section describes how to set the request payload data from POST requests. You can set custom request payload data on a span. Modifying the request payload data of a span will overwrite the data set by the AppSignal instrumentations. [All parameters are filtered](/guides/filter-data/filter-parameters) by our integrations before being sent to our servers. See the table below for a list of accepted root values per language. Each nested object can contain values that result in valid JSON (strings, integers, floats, booleans, nulls, etc.). | Language | Accepted root values | | -------- | ---------------------- | | Go | JSON serialized string | | Java | JSON serialized string | | PHP | Arrays, Objects | The below code sample shows how to set custom request payload data: <CodeGroup> ```go Go theme={null} // Additional setup is required to first fetch or create a new span import ( "encoding/json" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" ) payload := map[string]interface{}{ "param1": "value1", "param2": "value2", "nested": map[string]interface{}{ "param3": "value3", "param4": "value4", }, } json, _ := json.Marshal(payload) span.SetAttributes(attribute.String("appsignal.request.payload", string(json))) ``` ```java Java theme={null} // Additional setup is required to first fetch or create a new span import io.opentelemetry.api.trace.Span; // We're using the Jackson JSON library // You may need to add it to your project as a dependency import com.fasterxml.jackson.databind.ObjectMapper; import java.util.HashMap; import java.util.Map; Map<String, Object> payload = new HashMap<>(); payload.put("param1", "value1"); payload.put("param2", "value2"); Map<String, String> nested = new HashMap<>(); nested.put("param3", "value3"); nested.put("param4", "value4"); payload.put("nested", nested); try { ObjectMapper mapper = new ObjectMapper(); String jsonString = mapper.writeValueAsString(payload); Span span = Span.current(); span.setAttribute("appsignal.request.payload", jsonString); } catch (Exception e) { // Add error handling here } ``` ```php PHP theme={null} <?php use Appsignal\Appsignal; $payload = [ 'param1' => 'value1', 'param2' => 'value2', 'nested' => [ 'param3' => 'value3', 'param4' => 'value4', ], ]; Appsignal::setPayload($payload); ``` </CodeGroup> For certain languages, additional setup is required. Please follow the instructions for these languages: * [Go](/go/custom-instrumentation) * [Java](/java/custom-instrumentation) ## Limitations If the application sets request query parameters or request payload data multiple times, the Ruby gem will merge values at the root level. For other integrations, only the last set value is stored. # Add Request Session Data Source: https://docs.appsignal.com/guides/custom-data/request-session-data <Compatibility /> By default, the AppSignal integrations will track request session data for web applications in supported libraries. You can set custom request session data on a transaction or span. Modifying the session data will overwrite the data set by the AppSignal instrumentations. [All request session data is filtered](/guides/filter-data/filter-session-data) by our integrations before being sent to our servers. <Warning> πŸ” Do not send <strong>Personal Identifiable Information (PII)</strong> to AppSignal. Filter PII (e.g., names, emails) and use an ID, hash, or pseudonymized identifier instead. <br /> <br /> Use [Link Templates](https://docs.appsignal.com/application/link-templates) to link them back in your app. </Warning> See the table below for a list of accepted root values per language. Each nested object can contain values that result in valid JSON (strings, integers, floats, booleans, nulls, etc.). | Language | Accepted root values | | ---------- | ---------------------- | | Ruby | Arrays, Hashes | | JavaScript | Arrays, Objects | | Elixir | Lists, Maps | | Python | Lists, Maps | | Go | JSON serialized string | | Java | JSON serialized string | | PHP | Arrays, Objects | <CodeGroup> ```ruby Ruby theme={null} # Call `add_session_data` multiple times to set more session data Appsignal.add_session_data( :user_id => "123", :menu => { :type => "hamburger" } ) Appsignal.add_session_data(:menu => { :state => "closed" }) Appsignal.add_session_data(:menu => { :state => "open" }) # Session data: # { # :user_id => "123", # :menu => { :state => "open" } # } ``` ```elixir Elixir theme={null} Appsignal.Span.set_sample_data( Appsignal.Tracer.root_span, "session_data", %{user_id: "123", menu: "open"} ) ``` ```javascript Node.js theme={null} import { setSessionData } from "@appsignal/nodejs"; setSessionData({ user_id: "123", menu: "open" }); ``` ```python Python theme={null} from appsignal import set_session_data set_session_data({"user_id": "123", "menu": "open"}) ``` ```go Go theme={null} // Additional setup is required to first fetch or create a new span import ( "encoding/json" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" ) session_data := map[string]interface{}{ "key1": "value1", "key2": "value2", "nested": map[string]interface{}{ "key3": "value3", "key4": "value4", }, } json, _ := json.Marshal(session_data) span.SetAttributes(attribute.String("appsignal.request.session_data", string(json))) ``` ```java Java theme={null} // Additional setup is required to first fetch or create a new span import io.opentelemetry.api.trace.Span; // We're using the Jackson JSON library // You may need to add it to your project as a dependency import com.fasterxml.jackson.databind.ObjectMapper; import java.util.HashMap; import java.util.Map; Map<String, Object> sessionData = new HashMap<>(); sessionData.put("user_id", "123"); sessionData.put("menu", "open"); Map<String, String> nested = new HashMap<>(); nested.put("key3", "value3"); nested.put("key4", "value4"); sessionData.put("nested", nested); try { ObjectMapper mapper = new ObjectMapper(); String jsonString = mapper.writeValueAsString(sessionData); Span span = Span.current(); span.setAttribute("appsignal.request.session_data", jsonString); } catch (Exception e) { // Add error handling here } ``` ```php PHP theme={null} <?php use Appsignal\Appsignal; $data = [ 'param1' => 'value1', 'param2' => 'value2', 'nested' => [ 'param3' => 'value3', 'param4' => 'value4', ], ]; Appsignal::setSessionData($data); ``` </CodeGroup> For certain languages, additional setup is required. Please follow the instructions for these languages: * [Go](/go/custom-instrumentation) * [Java](/java/custom-instrumentation) <img alt="session_data" /> ## Limitations If the application sets session data multiple times, the Ruby gem will merge values at the root level. For other integrations, only the last set value is stored. # Reporting deploys to track improvements Source: https://docs.appsignal.com/guides/deploy-markers How your application functions can change with each new deployment. When tracking your deploys with AppSignal, error incidents and performance measurements are grouped per deployment, so you can easily see what impacts your deployment has had on your application's performance and error rate. AppSignal can take you from an [error backtrace][error backtrace links] to the line of code from which a specific error originated, and this help This guide will show you how to track deploys in AppSignal using deploy markers. <Tip> Read more in-depth information about [deploy markers][deploy markers] and what they're used for. </Tip> ## Configuring AppSignal This guide will use the `revision` config option method of reporting deploy markers. You can read about alternative approaches to this in our [Deploy Markers] documentation. The `revision` config option is configured differently per integration language. See the list of integrations below for the one your app uses. Note that AppSignal will [automatically report a deploy][automatic report] when using platforms such as Heroku or Render, or deployment orchestrators such as Kamal. ### Automatically Update the Revision We recommend dynamically fetching the revision config option value from the source control management used for your project (such as Git or SVN) on start or deploy. This way, the value doesn't have to be manually updated per deploy. If a Git commit hash is used, it will also be compatible with [error backtrace links]. Below is an example of how you would do this using Git: <CodeGroup> ```bash Bash theme={null} git rev-parse --short HEAD # Will output the current commit's short SHA ``` </CodeGroup> We'll continue to use Git for all integration examples in this documentation. ## Configurations per Language * [Ruby](#ruby) * [Elixir](#elixir) * [Node.js](#nodejs) * [Python](#python) * [Front-end JavaScript](#front-end-javascript) * [Go](#go) * [Java](#java) * [PHP](#php) ### Ruby For Ruby applications we will load the Git revision from the config file. The shell command that we run in the `revision` configuration option is the same command we used [previously](#automatically-update-the-revision) to retrieve the hash of the current commit. We call the `git rev-parse` command and set the output as the `revision` config option, as shown in the example below: <CodeGroup> ```ruby Ruby theme={null} Appsignal.configure do |config| config.revision = `git rev-parse --short HEAD`.strip end ``` ```yaml YAML theme={null} production: revision: "<%= `git rev-parse --short HEAD`.strip %>" # Other config options ``` </CodeGroup> #### Using Ruby deploy gems If you use a deployment tool like [Capistrano](https://github.com/capistrano/capistrano) or [Hatchbox](https://www.hatchbox.io/) that excludes the `.git` folder from getting deployed: * Modify the deploy process to run a command that creates a `REVISION` file in the `current` folder which contains the Git hash: `git rev-parse --short HEAD > REVISION` When using a Platform-as-a-Service provider, the provider might create this file for you, or expose the revision as an environment variable that you can read from the configuration file. If you are unsure if this applies to you, check with your provider or [get in touch](/support), we may know the answer. Below is an example of how to read the Git hash from a `REVISION` file when using `Rails`: <CodeGroup> ```ruby Ruby theme={null} Appsignal.configure do |config| revision = Rails.root.join("REVISION") if defined?(Rails) config.revision = revision.read.strip[0, 7] if revision&.exist? end ``` ```yaml YAML theme={null} production: <% revision = if (defined?(Rails)); Rails.root.join('REVISION'); end %> <% if revision&.exist? %> revision: "<%= revision.read.strip[0, 7] %>" <% end %> ``` </CodeGroup> [Read more about Ruby `revision` configuration option details](/ruby/configuration/options#option-revision) ### Elixir For Elixir applications we will load the Git revision in the `config/appsignal.exs` config file (your file location may differ). In the example `config/appsignal.exs` file below, we call the `git rev-parse` command with Elixir and set the output as the `revision` config option. <CodeGroup> ```elixir Elixir theme={null} # Example: config/appsignal.exs {revision, _exitcode} = System.cmd("git", ["log", "--pretty=format:%h", "-n 1"]) config :appsignal, :config, revision: revision # Other config options ``` </CodeGroup> [Read more about Elixir `revision` configuration option details](/elixir/configuration/options#option-revision) ### Node.js For Node.js applications, the Git revision is loaded in the app's config file. In the below `.js` snippet we call the `git rev-parse` command with Node.js and set the output as the `revision` config option. <CodeGroup> ```javascript Node.js theme={null} // Example: appsignal.js const childProcess = require("child_process"); const REVISION = childProcess.execSync("git rev-parse --short HEAD").toString(); const appsignal = new Appsignal({ revision: REVISION, // Other config }); module.exports = { appsignal }; ``` </CodeGroup> [Read more about Node.js `revision` configuration option details](/nodejs/3.x/configuration/options#option-revision) ### Python For Python applications, the Git revision is loaded in the application's `__appsignal__.py` config file. In the example below, we call the `git rev-parse` command with Python and set the output as the `revision` config option. The shell command that we run is the same command we used [previously](#automatically-update-the-revision) to retrieve the hash of the current commit. <CodeGroup> ```python Python theme={null} # Example: __appsignal__.py import subprocess from appsignal import Appsignal revision = subprocess.check_output( "git rev-parse --short HEAD", shell=True, text=True ).strip() appsignal = Appsignal( # Other config revision=revision ) ``` </CodeGroup> [Read more about the Python `revision` configuration option details](/python/configuration/options#option-revision) ### Front-end JavaScript Because Front-end JavaScript applications run in-browser, it is not possible to call the `git` executable command from your front-end application to get the current `revision`. There are two common approaches to pass the revision value to your front-end application: #### Using build-time environment variables (recommended for decoupled front-ends) Modern front-end build tools embed environment variables into your bundle at build time. You can pass the Git revision through one of these variables and reference it in your AppSignal config. The variable prefix and access pattern depend on your build tool. The example below uses **Vite**, which exposes environment variables prefixed with `VITE_` through the `import.meta.env` object. Set the variable before building: <CodeGroup> ```bash Bash theme={null} export VITE_REVISION=$(git rev-parse --short HEAD) npm run build ``` </CodeGroup> Then read it in the file where you configure AppSignal: <CodeGroup> ```javascript JavaScript theme={null} // Example: appsignal.js export const appsignal = new Appsignal({ revision: import.meta.env.VITE_REVISION, // Other config }); ``` </CodeGroup> Import the configured `appsignal` instance wherever you initialize your app. For example, in a Vue application's `main.js`: <CodeGroup> ```javascript JavaScript theme={null} // Example: main.js import { createApp } from "vue"; import App from "./App.vue"; import { appsignal } from "./appsignal"; import { errorHandler } from "@appsignal/vue"; const app = createApp(App); app.config.errorHandler = errorHandler(appsignal, app); app.mount("#app"); ``` </CodeGroup> #### Using a back-end rendered HTML attribute If your front-end is rendered by a back-end application (such as a Ruby or Elixir application), you can define the `revision` value in the HTML body as a data attribute: <CodeGroup> ```html HTML theme={null} <body data-app-revision="REVISION VALUE"> <!-- Rest of the HTML --> </body> ``` </CodeGroup> Then retrieve this value in your JavaScript: <CodeGroup> ```javascript JavaScript theme={null} // Example: appsignal.js const body = document.body; export const appsignal = new Appsignal({ revision: body.dataset.appRevision, // Other config }); ``` </CodeGroup> [Read more about JavaScript `revision` configuration option details](/front-end/configuration#option-revision) ### Go For Go applications, the revision is set on an OpenTelemetry resource attribute when OpenTelemetry is initialized. In the example below, we call the `git rev-parse` command and set the output as the `appsignal.config.revision` resource attribute. The shell command that we run is the same command we used [previously](#automatically-update-the-revision) to retrieve the hash of the current commit. <CodeGroup> ```go Go theme={null} import ( "os/exec" // And other imports ) var revision string cmd := exec.Command("git", "rev-parse", "--short", "HEAD") output, err := cmd.Output() if err != nil { revision = "unknown" } else { revision = strings.TrimSpace(string(output)) } res := resource.NewWithAttributes( resource.WithAttributes(attribute.String("appsignal.config.revision", revision)), // And other resource attributes ) ``` </CodeGroup> For Go applications the [`appsignal.config.revision` config option][go revision option] is required configuration, so it should already be set. Please consult the [`appsignal.config.revision` config option][go revision option] for more information. [go revision option]: /go/configuration/options.html#option-revision ### Java For Java applications, set the revision using the `OTEL_RESOURCE_ATTRIBUTES` environment variable. We'll use the same Git command as shown [previously](#automatically-update-the-revision). <CodeGroup> ```bash Bash theme={null} export OTEL_RESOURCE_ATTRIBUTES="\ appsignal.config.revision=$(git rev-parse --short HEAD),\ ..." ``` </CodeGroup> For Java applications the [`appsignal.config.revision` config option][java revision option] is required configuration, so it should already be set. Please consult the [`appsignal.config.revision` config option][java revision option] for more information. [java revision option]: /java/configuration/options.html#option-revision ### PHP For PHP applications, set the revision in your configuration to override the default. By default, AppSignal sets the revision using the same Git command shown in [Automatically update the revision](#automatically-update-the-revision). <CodeGroup> ```php PHP theme={null} $revision = trim(shell_exec('git rev-parse --short HEAD 2>/dev/null')) ?: 'unknown'; return [ 'revision' => $revision, // ... other options ]; ``` </CodeGroup> Please consult the [`appsignal.config.revision` config option][php revision option] for more information. [php revision option]: /php/configuration/options.html#option-revision ## Deploy When finished configuring the `revision` option, commit your changes and deploy your application. When the app starts/restarts, AppSignal will create a deploy in the [deploys section] for your app. That's it! You've successfully configured your application to notify AppSignal of deploys! Your application's data will be tracked alongside the appropriate deployment, helping level up your ability to analyze your application's performance. Are deploys not being reported or incorrectly? [Contact us][contact] and we will help you out! [deploy markers]: /application/markers/deploy-markers.html [automatic report]: /application/markers/deploy-markers.html#revision-config-option [error backtrace links]: /application/backtrace-links.html [deploys section]: https://appsignal.com/redirect-to/app?to=markers [contact]: mailto:support@appsignal.com # Filtering Application Data Source: https://docs.appsignal.com/guides/filter-data To help you find the cause of an issue, AppSignal gathers relevant error and performance measurement data by default. In some instances, your AppSignal integration may be collecting too much or too little app-specific data. <Warning> Your application should not collect user-identifiable information (such as personal names, email addresses, passwords, etc.). Use the tools described in this guide to limit and filter out this data. </Warning> You can configure AppSignal what kind of data it should not collect by filtering parameters, headers and session data: * [Filter request parameters](/guides/filter-data/filter-parameters) * [Filter request headers](/guides/filter-data/filter-headers) * [Filter session data](/guides/filter-data/filter-session-data) * [Filter function parameters](/guides/filter-data/filter-function-parameters) You can also configure AppSignal to ignore certain actions, errors, log messages and namespaces, based on their name or contents: * [Ignore actions](/guides/filter-data/ignore-actions) * [Ignore errors](/guides/filter-data/ignore-errors) * [Ignore logs](/guides/filter-data/ignore-logs) * [Ignore namespaces](/guides/filter-data/ignore-namespaces) # Filter function parameters Source: https://docs.appsignal.com/guides/filter-data/filter-function-parameters <Compatibility /> You can store function parameters for languages supported through our OpenTelemetry beta Storing function parameters makes it possible to view the parameters that background jobs or scripts started with. It's not meant to store the parameters for each function call in a trace, only the top-level parameters. Function parameter data may contain user-identifiable information such as email addresses, API tokens, etc. To protect your application's sensitive data, you must ensure this data is filtered out before being sent to the AppSignal servers. This way, your application doesn't leak any sensitive data. <Warning> Your application should not collect user-identifiable information (such as personal names, email addresses, passwords, etc.). Use the tools described in this guide to limit and filter out this data. </Warning> ## Function Parameter Filtering Function parameter filtering works with a denylist: a list of keys to filter out and not to send. You can set a "filter function parameters" option with a list of parameter keys to filter. Values of parameters you've configured to filter out will be replaced with a `[FILTERED]` value. This way, the list of parameters in the app data on AppSignal.com still includes the parameter key but not the value, so you still have visibility that a value had potentially sensitive data filtered out before being sent to AppSignal. ### Example For example, an application with this AppSignal config: <CodeGroup> ```yaml YAML theme={null} filter_function_parameters: ["secret_key"] ``` </CodeGroup> Results in this view for the parameters of a trace on AppSignal.com: <CodeGroup> ```json JSON theme={null} { "secret_key": "[FILTERED]" } ``` </CodeGroup> This guide will show you how to configure your application's function parameter filtering denylist based on what language your application uses: * [Go](#go) * [Java](#java) * [PHP](#php) ## Go Use the [`filter_function_parameters` denylist](/go/configuration/options#option-filter_function_parameters) for function parameter filtering. Set the [`send_function_parameters` option](/go/configuration/options#option-send_function_parameters) to `true` to avoid sending any function parameters. For more information on configuring OpenTelemetry for Go apps, see the [Go configuration page](/go/configuration/options). <CodeGroup> ```go Go theme={null} res := resource.NewWithAttributes( attribute.StringSlice("appsignal.config.filter_function_parameters", []string{"api_token", "secret"}), ) ``` </CodeGroup> ## Java Use the [`filter_function_parameters` denylist](/java/configuration/options#option-filter_function_parameters) for function parameter filtering. Set the [`send_function_parameters` option](/java/configuration/options#option-send_function_parameters) to `true` to avoid sending any function parameters. For more information on configuring OpenTelemetry for Java apps, see the [Java configuration page](/java/configuration/options). <CodeGroup> ```bash Bash theme={null} function encode() { echo -n "$@" | sed 's/,/%2C/g' } export OTEL_RESOURCE_ATTRIBUTES="\ appsignal.config.filter_function_parameters=$(encode "api_token,secret"),\ ..." ``` </CodeGroup> ## PHP Use the [`filter_function_parameters` denylist](/php/configuration/options#option-filter_function_parameters) for function parameter filtering. Set the [`send_function_parameters` option](/php/configuration/options#option-send_function_parameters) to `true` to avoid sending any function parameters. For more information on configuring AppSignal for PHP, see the [PHP configuration page](/php/configuration/options). <CodeGroup> ```php PHP theme={null} return [ 'filter_function_parameters' => ['api_token', 'secret'], // ... other options ]; ``` </CodeGroup> # Request Header Collection Source: https://docs.appsignal.com/guides/filter-data/filter-headers AppSignal collects headers for HTTP requests by default for supported frameworks. This data may help track down errors or performance issues that were caused by request header data a client is sending. In compliance with GDPR, AppSignal collects a minimal amount of headers by default. To comply with [GDPR](/appsignal/gdpr) rules, collecting no user identifiable data, AppSignal collects a very limited amount of headers by default. To further limit the collection of header data, you can configure which headers AppSignal collects. <Tip> Read more about request header filtering and what types of headers to set up filtering for in our [Request Header Collection][header filtering] documentation. </Tip> <Warning> πŸ” Do not send <strong>Personal Identifiable Information (PII)</strong> to AppSignal. Filter PII (e.g., names, emails) and use an ID, hash, or pseudonymized identifier instead. <br /> <br /> For <strong>HIPAA-covered entities</strong>, more info on signing a Business Associate Agreement (BAA) is available in our <a href="/support/business-add-ons">Business Add-Ons documentation</a>. </Warning> ## Configure Headers An application's session data can be filtered by configuring keys in an *allowlist*. This allowlist system will filter out all the session data keys not in this list. AppSignal does not collect the name or value of headers filtered out by your allowlist. ### Example For example, an application with this AppSignal config: <CodeGroup> ```yaml YAML theme={null} request_headers: ["Request-Method"] ``` </CodeGroup> Will only send the `Request-Method` header to AppSignal.com. This guide will show you how to configure your application's request header filtering allowlist based on what language your application uses: * [Ruby](#ruby) * [Elixir](#elixir) * [Node.js](#nodejs) * [Python](#python) * [Go](#go) * [Java](#java) * [PHP](#php) ## Ruby AppSignal automatically stores the configured request headers in the Ruby integration for Rails apps and other frameworks. It has a built-in list of request headers to collect by default that you can customize with the [`request_headers`][ruby request headers] config option. * [Default List of Request Headers][ruby request headers] To configure which request headers to collect for each request, add the following configuration to your `config/appsignal.yml` file in the environment group where you want it to apply. The [`request_headers`][ruby request headers] <CodeGroup> ```ruby Ruby theme={null} Appsignal.configure do |config| config.request_headers += ["ADDITONAL_CUSTOM_HEADER", "EXTRA_HEADER"] end ``` ```yaml YAML theme={null} production: request_headers: # Example list of headers - PATH_INFO - REQUEST_METHOD - REQUEST_PATH - SERVER_NAME - SERVER_PORT - SERVER_PROTOCOL ``` </CodeGroup> ## Elixir AppSignal automatically stores the configured request headers for Phoenix apps and other frameworks in the Elixir integration. It has a built-in list of request headers collected by default which you can customize using the [request\_headers][elixir request headers] config option. * [Default list of request headers][elixir request headers] To configure which request headers to collect for each request, add the following configuration to your `config/appsignal.exs` file in the environment group where you want it to apply. The [request\_headers][elixir request headers] value is a list of strings. <CodeGroup> ```yaml YAML theme={null} config :appsignal, :config, request_headers: ~w( path-info request-method request-uri server-name server-port server-protocol ) # Example list of headers ``` </CodeGroup> ## Node.js In the Node.js integration, AppSignal automatically stores the configured request headers for Express apps and other frameworks. It has a built-in list of request headers to collect by default that you can customize with the [requestHeaders][node request headers] config option. * [Default list of request headers][node request headers] To configure which request headers to collect for each request, add the following configuration to your AppSignal client instance creation. The [requestHeaders][node request headers] value is an array of strings. <CodeGroup> ```javascript Node.js theme={null} const { Appsignal } = require("@appsignal/nodejs"); new Appsignal({ requestHeaders: ["accept", "cache-control", "content-length", "range"], }); ``` </CodeGroup> ## Python In the Python integration, if an app sets request headers, AppSignal will automatically collect the configured request headers. It has a built-in list of request headers to collect by default that you can customize with the [request\_headers][python request headers] config option. * [Default list of request headers][python request headers] To configure which request headers to collect for each request, add the following configuration to your AppSignal client instance creation. The [`request_headers`][python request headers] value is a list of strings. <CodeGroup> ```python Python theme={null} from appsignal import Appsignal appsignal = Appsignal( # Other config request_headers: ["accept", "cache-control", "content-length", "range"], ) ``` </CodeGroup> ## Go If an app records request headers, AppSignal will automatically filter the configured request headers. It has a built-in list of request headers to collect by default that you can customize with the [`request_headers` config option][go request headers]. * [Default list of request headers][go request headers] See the [Go configuration page](/go/configuration/options) for more information on how to configure OpenTelemetry for Go apps. To configure which request headers to collect for each request, add the following configuration to your AppSignal client instance creation. The [`request_headers`][go request headers] value is a slice of strings. <CodeGroup> ```go Go theme={null} res := resource.NewWithAttributes( // Only send these specific headers attribute.StringSlice("appsignal.config.request_headers", []string{"accept", "request_method", "content_length"}), // Do not send any headers attribute.StringSlice("appsignal.config.request_headers", []string{}), ) ``` </CodeGroup> ## Java In the Java integration, if an app sets request headers, AppSignal will automatically collect the configured request headers. It has a built-in list of request headers to collect by default that you can customize with the [`request_headers`][java request headers] config option. * [Default list of request headers][java request headers] To configure which request headers to collect for each request, add the following configuration. The [`request_headers`][java request headers] value is an array of strings. <CodeGroup> ```bash Bash theme={null} function encode() { echo -n "$@" | sed 's/,/%2C/g' } export OTEL_RESOURCE_ATTRIBUTES="\ appsignal.config.request_headers=$(encode "accept,cache-control,content-length,range"),\ ..." # Do not send any headers export OTEL_RESOURCE_ATTRIBUTES="\ appsignal.config.request_headers=,\ ..." ``` </CodeGroup> ## PHP In the PHP integration, if an app sets request headers, AppSignal will automatically collect the configured request headers. It has a built-in list of request headers to collect by default that you can customize with the [`request_headers`][php request headers] config option. * [Default list of request headers][php request headers] To configure which request headers to collect for each request, add the following configuration. The [`request_headers`][php request headers] value is an array of strings. <CodeGroup> ```php PHP theme={null} return [ // Send selected headers 'request_headers' => ['accept', 'cache-control', 'content-length', 'range'], // Do not send any headers 'request_headers' => [], // ... other options ]; ``` </CodeGroup> [disabled entirely]: /application/header-filtering.html#filter-all-request-headers [elixir request headers]: /elixir/configuration/options.html#option-request_headers [header filtering]: /application/header-filtering.html [node request headers]: /nodejs/3.x/configuration/options.html#option-requestheaders [ruby request headers]: /ruby/configuration/options.html#option-request_headers [python request headers]: /python/configuration/options.html#option-request_headers [go request headers]: /go/configuration/options.html#option-request_headers [java request headers]: /java/configuration/options.html#option-request_headers [php request headers]: /php/configuration/options.html#option-request_headers # Filter request parameters Source: https://docs.appsignal.com/guides/filter-data/filter-parameters Every time a request is made on your application, AppSignal collects the parameters sent with that request. This includes form data (POST), query parameters, and keys in routes (e.g., /user/:id/) in some frameworks. This data could contain user-identifiable information such as names, email addresses, passwords, two-factor authentication codes, API tokens, etc. To protect your application's sensitive data, you must ensure this data is filtered out before being to the AppSignal servers. This way, your application doesn't leak any sensitive data. <Tip> Read more about parameter filtering in our [Parameter Filtering][parameter filtering] documentation. </Tip> <Warning> Your application should not collect user-identifiable information (such as personal names, email addresses, passwords, etc.). Use the tools described in this guide to limit and filter out this data. </Warning> ## Parameter Filtering Basic parameter filtering in the AppSignal integrations works with a denylist, a list of keys to filter out and to not send. You can set a "filter parameters" option in the AppSignal configuration with a list of parameter keys to filter. Parameter values you've configured to filter out by will be replaced with a `[FILTERED]` value. This way, the list of parameters in the app data on AppSignal.com still includes the parameter key but not the value, so you still have visibility that a value had potentially sensitive data filtered out before being sent to AppSignal. <Tip> Some [parameter keys are also removed by our processor](/application/parameter-filtering#processor-parameter-filtering) on our servers. </Tip> ### Example For example, an application with this AppSignal config: <CodeGroup> ```yaml YAML theme={null} filter_parameters: ["password"] ``` </CodeGroup> Results in this view for the parameters of a web request on AppSignal.com: <CodeGroup> ```json JSON theme={null} { "password": "[FILTERED]" } ``` </CodeGroup> This guide will show you how to configure your application's parameter filtering denylist based on what language your application uses: * [Ruby](#ruby) * [Elixir](#elixir) * [Node.js](#nodejs) * [Python](#python) * [Go](#go) * [Java](#java) * [PHP](#php) ## Ruby The [AppSignal for Ruby](/ruby) gem has two parameter filtering methods: * If your app uses Rails, you can use the [Rails configuration directly](/guides/filter-data/filter-parameters#rails-parameter-filtering). * If your app uses another framework, like Sinatra or Padrino, you can use [AppSignal's built-in filtering](#rails-parameter-filtering) instead. ### AppSignal Parameter Filtering Use the denylist for basic parameters filtering. This parameter filtering is applied to any query parameters in an HTTP request and any argument for background jobs. This filtering supports key based filtering for hashes, which will have their values replaced with `[FILTERED]`. There's support for nested hashes and nested hashes in arrays. Any hash we encounter in your parameters will be filtered. To use this filtering, add the following to your `config/appsignal.yml` file in the environment group you want it to apply. The [`filter_parameters`](/ruby/configuration/options#option-filter_parameters) value is an array of strings. <CodeGroup> ```ruby Ruby theme={null} Appsignal.configure do |config| config.filter_parameters << "password" end ``` ```yaml YAML theme={null} production: filter_parameters: - password - confirm_password ``` </CodeGroup> ### Rails Parameter Filtering Luckily Rails provides a request parameter filtering mechanism to scrub data from log files. AppSignal leverages this request parameter mechanism so both your request logs and the request data sent to AppSignal are filtered by one configuration. Suppose the application should filter the same keys for request parameters and job arguments reported for different Ruby gems, like Sidekiq job arguments. In that case, it's necessary to configure the parameter filtering in AppSignal using the [`filter_parameters` option](/ruby/configuration/options#option-filter_parameters) to also include the keys set in the Rails config as it will not reuse the Rails parameter filtering configuration for those gems. #### Denylist: Filtering Specific Keys There are two ways to determine which keys get filtered. The first one is adding specific keys to the denylist. In the below example, the value of `:secret` in any post in the app will be replaced with `[FILTERED]`. <CodeGroup> ```ruby Ruby theme={null} module Blog class Application < Rails::Application config.filter_parameters << :secrets end end ``` </CodeGroup> The downside of this approach is that it is more complicated when dealing with larger, more complex applications, especially when using features like `accepts_nested_attributes_for`. If we forget to explicitly add keys, they will not be filtered. #### Allowlist: Allowing Specific Keys Using a lambda instead of a list of keys gives more flexibility. In the following example, we use a lambda to set up an allowlist instead of a denylist. <CodeGroup> ```ruby Ruby theme={null} ALLOWED_KEYS_MATCHER = /((^|_)ids?|action|controller|code$)/.freeze SANITIZED_VALUE = '[FILTERED]'.freeze Rails.application.config.filter_parameters << lambda do |key, value| unless key.match(ALLOWED_KEYS_MATCHER) value.replace(SANITIZED_VALUE) if value.is_a?(String) end end ``` </CodeGroup> You can make the lambda check any key you'd like, so you can determine and use a filtering method that best suits your application's needs. Some further information about filtering parameters can be found in the Rails guides about [ActionController](http://guides.rubyonrails.org/action_controller_overview.html#parameters-filtering). ## Elixir If your app uses Phoenix, you can use the [Phoenix parameter filtering](/guides/filter-data/filter-parameters#phoenix-filter_parameters-configuration). You can use AppSignal's built-in filtering if your app uses a different Elixir framework. ### AppSignal parameter filtering Use the denylist for basic parameters filtering. This parameter filtering is applied to any query parameters in an HTTP request. Set up parameter filtering using the [`filter_parameters` config option](/elixir/configuration/options#option-filter_parameters). The filter\_parameters value is a List of Strings. <CodeGroup> ```elixir Elixir theme={null} config :appsignal, :config, filter_parameters: ["password", "secret"] ``` </CodeGroup> ### Phoenix filter\_parameters Configuration Use Phoenix's parameter filtering to centralize your config, which is used to keep sensitive information from the logs. AppSignal will follow these filtering rules. <CodeGroup> ```elixir Elixir theme={null} config :phoenix, :filter_parameters, ["password", "secret"] ``` </CodeGroup> If the `filter_parameters` config option is not set, Phoenix will default to `["password"]` as a config. This means that a Phoenix app will not send any passwords to AppSignal without any configuration. ## Node.js Use the `filterParameters` denylist for basic parameter filtering. This filtering is applied to all parameters of an HTTP request. You can set up parameter filtering using the [`filterParameters` config option](/nodejs/3.x/configuration/options#option-filterparameters). The `filterParameters` value is an array of strings. <CodeGroup> ```javascript Node.js theme={null} const { Appsignal } = require("@appsignal/nodejs"); new Appsignal({ // Other config options filterParameters: ["password", "secret"], }); ``` </CodeGroup> ## Python Use the `filter_parameters` denylist for basic parameter filtering. This filtering is applied to all parameters of an HTTP request. You can set up parameter filtering using the [`filter_parameters` config option](/python/configuration/options#option-filter_parameters). The `filter_parameters` value is an array of strings. <CodeGroup> ```python Python theme={null} from appsignal import Appsignal appsignal = Appsignal( # Other config filter_parameters: ["password", "secret"] ) ``` </CodeGroup> ## Go For Go, we report the request parameters as query parameters (`?query=text`) and payload data (POST request payload). Use the [`filter_request_query_parameters` denylist](/go/configuration/options#option-filter_request_query_parameters) for request query parameter filtering. Set the [`send_request_query_parameters` option](/go/configuration/options#option-send_request_query_parameters) to `false` to not send any request query parameters at all. Use the [`filter_request_payload` denylist](/go/configuration/options#option-filter_request_payload) for request payload data filtering. Set the [`send_request_payload` option](/go/configuration/options#option-send_request_payload) to `false` to not send any request payload data at all. See the [Go configuration page](/go/configuration/options) for more information on how to configure OpenTelemetry for Go apps. <CodeGroup> ```go Go theme={null} res := resource.NewWithAttributes( attribute.StringSlice("appsignal.config.filter_request_query_parameters", []string{"password", "cvv"}), attribute.StringSlice("appsignal.config.filter_request_payload", []string{"password", "cvv"}), ) ``` </CodeGroup> ## Java For Java, we report the request parameters as query parameters (`?query=text`) and payload data (POST request payload). Use the [`filter_request_query_parameters` denylist](/java/configuration/options#option-filter_request_query_parameters) for request query parameter filtering. Set the [`send_request_query_parameters` option](/java/configuration/options#option-send_request_query_parameters) to `false` to not send any request query parameters at all. Use the [`filter_request_payload` denylist](/java/configuration/options#option-filter_request_payload) for request payload data filtering. Set the [`send_request_payload` option](/java/configuration/options#option-send_request_payload) to `false` to not send any request payload data at all. See the [Java configuration page](/java/configuration/options) for more information on how to configure OpenTelemetry for Java apps. <CodeGroup> ```bash Bash theme={null} function encode() { echo -n "$@" | sed 's/,/%2C/g' } export OTEL_RESOURCE_ATTRIBUTES="\ appsignal.config.filter_request_query_parameters=$(encode "password,cvv"),\ appsignal.config.filter_request_payload=$(encode "password,cvv"),\ ..." ``` </CodeGroup> ## PHP For PHP, we report the request parameters as query parameters (`?query=text`) and payload data (POST request payload). Use the [`filter_request_query_parameters` denylist](/php/configuration/options#option-filter_request_query_parameters) for request query parameter filtering. Set the [`send_request_query_parameters` option](/php/configuration/options#option-send_request_query_parameters) to `false` to not send any request query parameters at all. Use the [`filter_request_payload` denylist](/php/configuration/options#option-filter_request_payload) for request payload data filtering. Set the [`send_request_payload` option](/php/configuration/options#option-send_request_payload) to `false` to not send any request payload data at all. See the [PHP configuration page](/php/configuration/options) for more information on how to configure AppSignal for PHP. <CodeGroup> ```php PHP theme={null} return [ 'filter_request_query_parameters' => ['password', 'cvv'], 'filter_request_payload' => ['password', 'cvv'], // ... other options ]; ``` </CodeGroup> [parameter filtering]: /application/parameter-filtering.html # Filter Session Data Source: https://docs.appsignal.com/guides/filter-data/filter-session-data Every time a request is made on a web app, AppSignal collects the session data that were sent with the request for supported frameworks. Sessions contain data specific to your application, but some dependencies an app uses may store data here as well. For example: when a user signs in, some data of the user who is signed in is stored in a session. Sessions can contain sensitive or personally identifiable information that should not leave the app. Make sure this data is filtered out before it is sent to the AppSignal servers, this way the app doesn't leak any sensitive data. <Tip> Read more about session data filtering and what types of session data to set up filtering for in our [session data filtering topic][session data filtering]. </Tip> <Warning> πŸ” Do not send <strong>Personal Identifiable Information (PII)</strong> to AppSignal. Filter PII (e.g., names, emails) and use an ID, hash, or pseudonymized identifier instead. <br /> <br /> For <strong>HIPAA-covered entities</strong>, more info on signing a Business Associate Agreement (BAA) is available in our <a href="/support/business-add-ons">Business Add-Ons documentation</a>. </Warning> ## Session Data Filtering Basic session data filtering in the AppSignal integrations works with a denylist, a list of keys to filter out and to not send. In the integrations it's possible to set a "filter session data" option in the AppSignal configuration with a list of session data keys to filter. Any session data values that are filtered out by these systems will be replaced with a `[FILTERED]` value. This way the list of session data in the app data on AppSignal.com still includes the session data key, but not the value. Making it easier to see that a value was sent, but the potentially sensitive data was filtered out. ### Example For example, an application with this AppSignal config: <CodeGroup> ```yaml YAML theme={null} filter_session_data: ["password"] ``` </CodeGroup> Results in this view for the session data of a web request on AppSignal.com: <CodeGroup> ```json JSON theme={null} { "password": "[FILTERED]" } ``` </CodeGroup> This guide will show you how to configure your application's session filtering denylist based on what language your application uses: * [Ruby](#ruby) * [Elixir](#elixir) * [Node.js](#nodejs) * [Python](#python) * [Go](#go) * [Java](#java) * [PHP](#php) ## Ruby In the Ruby integration, AppSignal automatically stores the contents of the user's session for Rails apps and other frameworks. Specific values can be filtered out or it can be [disabled entirely]. In session data filtering, there's support for nested hashes and nested hashes in arrays. Any hash we encounter in your session data will be filtered. To use this filtering, add the following to your `config/appsignal.yml` file in the environment group you want it to apply. The [`filter_session_data`](/ruby/configuration/options#option-filter_session_data) value is an Array of Strings. <CodeGroup> ```ruby Ruby theme={null} Appsignal.configure do |config| config.filter_session_data += ["name", "email", "api_token", "token"] end ``` ```yaml YAML theme={null} production: filter_session_data: - name - email - api_token - token ``` </CodeGroup> ## Elixir In the Elixir integration, AppSignal automatically stores the contents of the user's session for Phoenix apps. Specific values can be filtered out or it can be [disabled entirely]. In the session data filtering, there's support for nested hashes and nested hashes in arrays. Any hash we encounter in your session data will be filtered. To use this filtering, add the following to your `config/appsignal.exs` file. The [`filter_session_data`](/elixir/configuration/options#option-filter_session_data) value is an Array of Strings. <CodeGroup> ```elixir Elixir theme={null} config :appsignal, :config, filter_session_data: ["name", "email", "api_token", "token"] ``` </CodeGroup> ## Node.js If a request stores session data on the sample, use the session data filter to filter out any data you do not want to include. In the session data filtering, there's support for nested hashes and nested hashes in arrays. Any hash we encounter in your session data will be filtered. To use this filtering, use the [`filterSessionData`](/nodejs/3.x/configuration/options#option-filtersessiondata) config option to select which session data keys to filter out. <CodeGroup> ```javascript Node.js theme={null} const { Appsignal } = require("@appsignal/nodejs"); new Appsignal({ // Other config options filterSessionData: ["name", "email", "api_token", "token"], }); ``` </CodeGroup> ## Python If a request stores session data on the sample, use the session data filter to filter out any data you do not want to include. In the session data filtering, there's support for nested hashes and nested dictionaries in lists. Any dictionary we encounter in your session data will be filtered. To use this filtering, use the [`filter_session_data`](/python/configuration/options#option-filter_session_data) config option to select which session data keys to filter out. <CodeGroup> ```python Python theme={null} from appsignal import Appsignal appsignal = Appsignal( # Other config filter_session_data: ["name", "email", "api_token", "token"] ) ``` </CodeGroup> ## Go If a request stores session data on the sample, use the session data filter to filter out any data you do not want to include. In the session data filtering, there's support for nested slices and nested maps. Any map we encounter in your session data will be filtered. Use the [`filter_request_session_data` denylist](/go/configuration/options#option-filter_request_session_data) for request session data filtering. Set the [`send_request_session_data` option](/go/configuration/options#option-send_request__session_data) to `false` to not send any request session data at all. See the [Go configuration page](/go/configuration/options) for more information on how to configure OpenTelemetry for Go apps. <CodeGroup> ```go Go theme={null} res := resource.NewWithAttributes( attribute.StringSlice("appsignal.config.filter_session_data", []string{"password", "cvv"}), ) ``` </CodeGroup> ## Java If a request stores session data on the sample, use the session data filter to filter out any data you do not want to include. In the session data filtering, there's support for nested maps and arrays. Any map encountered in your session data will be filtered. Use the [`filter_request_session_data`](/java/configuration/options#option-filter_request_session_data) denylist for session data filtering. Set the [`send_request_session_data` option](/java/configuration/options#option-send_request_session_data) to `false` to avoid sending any session data. See the [Java configuration page](/java/configuration/options) for more information on how to configure OpenTelemetry for Java apps. <CodeGroup> ```bash Bash theme={null} function encode() { echo -n "$@" | sed 's/,/%2C/g' } export OTEL_RESOURCE_ATTRIBUTES="\ appsignal.config.filter_request_session_data=$(encode "name,email,api_token,token"),\ ..." ``` </CodeGroup> ## PHP If a request stores session data on the sample, use the session data filter to filter out any data you do not want to include. In the session data filtering, there's support for nested arrays. Any array encountered in your session data will be filtered. Use the [`filter_request_session_data`][php filter_request_session_data] denylist for session data filtering. Set the [`send_request_session_data`][php send_request_session_data] option to `false` to avoid sending any session data. <CodeGroup> ```php PHP theme={null} return [ 'filter_request_session_data' => ['name', 'email', 'api_token', 'token'], // ... other options ]; ``` </CodeGroup> [session data filtering]: /application/session-data-filtering.html [disabled entirely]: /application/session-data-filtering.html#filter-all-session-data [php filter_request_session_data]: /php/configuration/options.html#option-filter_request_session_data [php send_request_session_data]: /php/configuration/options.html#option-send_request_session_data # Ignore Actions Source: https://docs.appsignal.com/guides/filter-data/ignore-actions <Tip> Ignoring actions will **ignore error and performance data** from those actions. [Custom metrics data](/metrics/custom) and [logs](/logging) recorded in an action will still be reported. </Tip> There may be specific actions in your application you don't want to report to AppSignal. The most common use case is a web endpoint that your load balancer uses to check if your application is still responding or all actions that occur within your application's admin panel. These endpoints may receive a lot of traffic but are not crucial endpoints to have AppSignal monitor and may disrupt the usability of metrics AppSignal provides you for your application's [namespaces](/application/namespaces). # Ignoring Actions <Tip> If you're unsure of the action names to configure in your application configuration, find the action name to ignore in your application on AppSignal.com, and copy it into your AppSignal configuration. </Tip> Specific actions can ignore actions by using the "ignore actions" option in your application's AppSignal integration configuration. The "ignore actions" configuration option allows you to define a denylist of actions you want to ignore. All actions in this list will be ignored, meaning the data from these actions will not be sent to the AppSignal servers and will not count towards your [organization's billing plan](https://www.appsignal.com/plans). This guide will show you how to configure your ignore action denylist in the language your application uses: * [Ruby](#ruby) * [Elixir](#elixir) * [Node.js](#nodejs) * [Python](#python) * [Go](#go) * [Java](#java) * [PHP](#php) **Note:** This configuration is not available for Front-end JavaScript. ## Ruby To ignore actions in Ruby, add the following to your AppSignal configuration file. The [`ignore_actions`][ruby ignore_actions] value is an Array of Strings. The below example is for a Rails application. <CodeGroup> ```ruby Ruby theme={null} Appsignal.configure do |config| config.ignore_actions += [ "UptimeController#healthcheck", "AdminController#index", "Admin::UsersController#show" ] end ``` ```yaml YAML theme={null} production: ignore_actions: - "UptimeController#healthcheck" - "AdminController#index" - "Admin::UsersController#show" ``` </CodeGroup> If you use Sinatra or any other framework, use the HTTP method and path you used to specify your route, for example: <CodeGroup> ```ruby Ruby theme={null} Appsignal.configure do |config| config.ignore_actions += [ "GET /healthcheck", "GET /pages/:id", "POST /pages/create" ] end ``` ```yaml YAML theme={null} production: ignore_actions: - "GET /healthcheck" - "GET /pages/:id" - "POST /pages/create" ``` </CodeGroup> [ruby ignore_actions]: /ruby/configuration/options.html#option-ignore_actions ## Elixir To ignore actions in Elixir, add the following to your AppSignal configuration file. The [`ignore_actions`][elixir ignore_actions] value is a List of Strings. <CodeGroup> ```elixir Elixir theme={null} config :appsignal, :config, ignore_actions: ["AppsignalPhoenixExampleWeb.UptimeController#healthcheck", "AppsignalPhoenixExampleWeb.AdminController#index"] ``` </CodeGroup> [elixir ignore_actions]: /elixir/configuration/options.html#option-ignore_actions ## Node.js To ignore actions in Node.js, add the following to your AppSignal configuration file. The [`ignoreActions`][nodejs ignore_actions] value is an Array of Strings. Action names are used to group errors and performance issues. Their names are usually a controller/endpoint or background job. You can see a list of these in the "Action name" column of the *Issue list* under [Performance](https://appsignal.com/redirect-to/app?to=performance) in the sidebar. To ignore a specific action, copy the name as it appears in the UI and add it to the `ignoreActions` option. <CodeGroup> ```javascript Node.js theme={null} const { Appsignal } = require("@appsignal/nodejs"); new Appsignal({ // Other config ignoreActions: ["GET /pages/:id", "GET /healthcheck", "GET /admin"], }); ``` </CodeGroup> [nodejs ignore_actions]: /nodejs/3.x/configuration/options.html#option-ignoreactions ## Python To ignore actions in Python, add the following to your AppSignal configuration file. The [`ignore_actions`][python ignore_actions] value is a list of strings. Action names are used to group errors and performance issues. Their names are usually a controller/endpoint or background job. You can see a list of these in the "Action name" column of the *Issue list* under [Performance](https://appsignal.com/redirect-to/app?to=performance) in the sidebar. To ignore a specific action, copy the name as it appears in the UI and add it to the `ignore_actions` option. <CodeGroup> ```python Python theme={null} from appsignal import Appsignal appsignal = Appsignal( # Other config ignore_actions=["GET /pages/:id", "GET /healthcheck", "GET /admin"] ) ``` </CodeGroup> [python ignore_actions]: /python/configuration/options.html#option-ignore_actions ## Go To ignore actions in Go applications, configure the [`ignore_actions`][go ignore_actions] config option. Action names are used to group errors and performance issues. Their names are usually a controller/endpoint or background job. You can see a list of these in the "Action name" column of the *Issue list* under [Performance](https://appsignal.com/redirect-to/app?to=traces) in the sidebar. To ignore a specific action, copy the name as it appears in the UI and add it to the `ignore_actions` option. See the [Go configuration page](/go/configuration/options) for more information on how to configure OpenTelemetry for Go apps. <CodeGroup> ```go Go theme={null} res := resource.NewWithAttributes( attribute.StringSlice("appsignal.config.ignore_actions", []string{"GET /heath_check", "POST /ping"}), // And other resource attributes ) ``` </CodeGroup> [go ignore_actions]: /go/configuration/options.html#option-ignore_actions ## Java To ignore actions in Java applications, configure the [`ignore_actions`][java ignore_actions] option. Action names are used to group errors and performance issues. Their names are usually a controller/endpoint or background job. You can see a list of these in the "Action name" column of the *Issue list* under [Performance](https://appsignal.com/redirect-to/app?to=traces) in the sidebar. To ignore a specific action, copy the name as it appears in the UI and add it to the `ignore_actions` option. See the [Java configuration page](/java/configuration/options) for more information on how to configure OpenTelemetry for Java apps. <CodeGroup> ```bash Bash theme={null} function encode() { echo -n "$@" | sed 's/,/%2C/g' } export OTEL_RESOURCE_ATTRIBUTES="\ appsignal.config.ignore_actions=$(encode "UptimeController#healthcheck,AdminController#index"),\ ..." ``` </CodeGroup> ### Read More * Read more about the [Java `ignore_actions` config option][java ignore_actions]. [java ignore_actions]: /java/configuration/options.html#option-ignore_actions ## PHP To ignore actions in PHP applications, configure the [`ignore_actions`][php ignore_actions] option. <CodeGroup> ```php PHP theme={null} return [ 'ignore_actions' => ['GET /admin', 'GET /ignored-route'], // ... other options ]; ``` </CodeGroup> ### Read More * Read more about the [PHP `ignore_actions` config option][php ignore_actions]. [php ignore_actions]: /php/configuration/options.html#option-ignore_actions [notifications]: /application/notification-settings.html # Ignore Errors Source: https://docs.appsignal.com/guides/filter-data/ignore-errors Errors (or exceptions) raised by your application will be visible in the [Error incident list][error incident list]. You may find AppSignal notifying you of errors you do not consider important. To prevent this, you can add a list of errors to an ignore list in your application's configuration. AppSignal will then only notify you of errors that are not on the ignore list. <Note> πŸ”• If you want AppSignal to mute error notifications rather than ignore them, [read our Notification Settings][notifications] Documentation to learn how to customize your application's notification settings. </Note> ## Ignoring errors To ignore errors you can configure an "ignore errors" *denylist* in your AppSignal integration configuration. By adding error names to this list the integrations will filter out ignored errors from data sent to AppSignal. This guide will show you how to configure your ignore errors denylist based on what language your application uses: * [Ruby](#ruby) * [Elixir](#elixir) * [Node.js](#nodejs) * [Python](#python) * [Front-end JavaScript](#front-end-javascript) * [Go](#go) * [Java](#java) * [PHP](#php) <Tip> It's not possible to ignore all errors, or disable error reporting entirely. It is possible to [disable notifications for errors][notifications]. </Tip> ## Ruby To ignore errors in Ruby, add the following to your AppSignal configuration file. The [`ignore_errors`][ruby ignore_errors] value is an Array of Strings. <CodeGroup> ```ruby Ruby theme={null} Appsignal.configure do |config| config.ignore_errors += ["ActiveRecord::RecordNotFound", "ActionController::RoutingError"] end ``` ```yaml YAML theme={null} production: ignore_errors: - ActiveRecord::RecordNotFound - ActionController::RoutingError ``` </CodeGroup> <Warning> Names set in [`ignore_errors`][ruby ignore_errors] will be matched on class name and not class inheritance. If you want to match all subclasses of a certain Exception, all subclasses have to be listed separately. </Warning> ### Read More * Read more about the [Ruby `ignore_errors` config option][ruby ignore_errors]. * [Exception handling with AppSignal in Ruby](/ruby/instrumentation/exception-handling). ## Elixir To ignore errors in Elixir, add the following to your AppSignal configuration file. The [`ignore_errors`][elixir ignore_errors] value is a List of Strings. <CodeGroup> ```elixir Elixir theme={null} config :appsignal, :config, ignore_errors: ["SpecificError", "AnotherError"] ``` </CodeGroup> <Warning> Names set in [`ignore_errors`][elixir ignore_errors] will be matched on module name. </Warning> ### Read More * Read more about the [Elixir `ignore_errors` config option][elixir ignore_errors]. * [Exception handling with AppSignal in Elixir](/elixir/instrumentation/exception-handling). ## Node.js To ignore errors in Node.js, add the following to your AppSignal configuration file. The [`ignoreErrors`][nodejs ignore_errors] value is an Array of Strings. <CodeGroup> ```javascript Node.js theme={null} const { Appsignal } = require("@appsignal/nodejs"); new Appsignal({ // Other config ignoreErrors: ["SpecificError", "AnotherError"], }); ``` </CodeGroup> <Warning> Names set in [`ignoreErrors`][nodejs ignore_errors] will be matched on the `Error` objects `name` property only, and will not honor any class inheritance. If you want to match subclasses of `Error`, each subclass has to be listed separately. </Warning> ### Read More * Read more about the [Node.js `ignoreErrors` config option][nodejs ignore_errors]. * [Exception handling with AppSignal in Node.js](/nodejs/3.x/instrumentation/exception-handling). ## Python To ignore errors in Python, add the following to your AppSignal configuration file. The [`ignore_errors`][python ignore_errors] value is a list of strings. <CodeGroup> ```python Python theme={null} from appsignal import Appsignal appsignal = Appsignal( # Other config ignore_errors: ["SpecificError", "AnotherError"], ) ``` </CodeGroup> <Warning> Names set in [`ignore_errors`][python ignore_errors] will be matched on the Exception class name only, and will not honor any class inheritance. If you want to match subclasses of `Exception`, each subclass has to be listed separately. </Warning> ### Read More * Read more about the [Python `ignore_errors` config option][python ignore_errors]. * [Exception handling with AppSignal in Python](/python/instrumentation/exception-handling). ## Front-end JavaScript To ignore errors in Front-end JavaScript, add the following to your AppSignal configuration file. The [`ignoreErrors`][js ignore_errors] value is an Array of Regular expressions. <CodeGroup> ```javascript JavaScript theme={null} import Appsignal from "@appsignal/javascript"; export const appsignal = new Appsignal({ // Other config ignoreErrors: [/a specific error message/, /another error message/], }); ``` </CodeGroup> <Warning> Names set in [`ignoreErrors`][js ignore_errors] will be matched by using a regular expression. The regular expression is matched `message` property of a given `Error`. </Warning> ### Read More * Read more about the [front-end JavaScript `ignoreErrors` config option][js ignore_errors]. * [Exception handling with AppSignal in front-end JavaScript](/front-end/error-handling). ## Go To ignore errors in Go applications, configure the [`ignore_errors` config option][go ignore_errors]. Error names are matched exactly by their name, not by inheritance. You can see a list of errors in the "Action and error type" column of the *Issue list* under [Errors](https://appsignal.com/redirect-to/app?to=exceptions) in the sidebar. To ignore a specific error, copy the name as it appears in the UI and add it to the `ignore_errors` option. See the [Go configuration page](/go/configuration/options) for more information on how to configure OpenTelemetry for Go apps. <CodeGroup> ```go Go theme={null} res := resource.NewWithAttributes( attribute.StringSlice("appsignal.config.ignore_errors", []string{"MyCustomError", "ExpectedError"}), // And other resource attributes ) ``` </CodeGroup> ### Read More * Read more about the [Go `ignore_errors` config option][go ignore_errors]. ## Java To ignore errors in Java applications, configure the [`ignore_errors` config option](/java/configuration/options#option-ignore_errors) using the `OTEL_RESOURCE_ATTRIBUTES` environment variable. Error names are matched exactly by their name, not by inheritance. You can see a list of errors in the "Action and error type" column of the *Issue list* under [Errors](https://appsignal.com/redirect-to/app?to=exceptions) in the sidebar. To ignore a specific error, copy the name as it appears in the UI and add it to the `ignore_errors` option. See the [Java configuration page](/java/configuration/options) for more information on how to configure OpenTelemetry for Java apps. <CodeGroup> ```bash Bash theme={null} function encode() { echo -n "$@" | sed 's/,/%2C/g' } export OTEL_RESOURCE_ATTRIBUTES="\ appsignal.config.ignore_errors=$(encode "MyCustomError,ExpectedError"),\ ..." ``` </CodeGroup> <Warning> Names set in [`ignore_errors`](/java/configuration/options#option-ignore_errors) will be matched on the Exception class name only, and will not honor any class inheritance. If you want to match subclasses of `Exception`, each subclass has to be listed separately. </Warning> ### Read More * Read more about the [Java `ignore_errors` config option](/java/configuration/options#option-ignore_errors). ## PHP To ignore errors in PHP applications, configure the [`ignore_errors` config option](/php/configuration/options#option-ignore_errors). <CodeGroup> ```php PHP theme={null} return [ 'ignore_errors' => ['SpecificError', 'AnotherError'], // ... other options ]; ``` </CodeGroup> <Warning> Names set in [`ignore_errors`](/php/configuration/options#option-ignore_errors) will be matched on the Exception class name only, and will not honor any class inheritance. If you want to match subclasses of `Exception`, each subclass has to be listed separately. </Warning> ### Read More * Read more about the [PHP `ignore_errors` config option](/php/configuration/options#option-ignore_errors). [elixir ignore_errors]: /elixir/configuration/options.html#option-ignore_errors [error incident list]: https://appsignal.com/redirect-to/app?to=exceptions [js ignore_errors]: /front-end/configuration/ [nodejs ignore_errors]: /nodejs/3.x/configuration/options.html#option-ignoreerrors [notifications]: /application/notification-settings.html [ruby ignore_errors]: /ruby/configuration/options.html#option-ignore_errors [python ignore_errors]: /python/configuration/options.html#option-ignore_errors [go ignore_errors]: /go/configuration/options.html#option-ignore_errors # Ignore Logs Source: https://docs.appsignal.com/guides/filter-data/ignore-logs When using [AppSignal Logging](/logging), log lines emitted [using the AppSignal Integrations](/logging/integrations) can be filtered using our "ignore logs" denylist. Ignoring log lines allows you to remove noise from the logs you view in AppSignal, keeping only those log lines that are meaningful to you. Ignored log lines are not sent to AppSignal, and are not counted towards your log storage quota. ## Ignoring logs To ignore logs you can configure an "ignore logs" *denylist* in your AppSignal integration configuration. By adding log messages to this list the integrations will filter out log lines containing those messages from data sent to AppSignal. This guide will show you how to configure your ignore errors denylist based on what language your application uses: * [Ruby](#ruby) * [Elixir](#elixir) * [Node.js](#nodejs) * [Go](#go) * [Java](#java) * [PHP](#php) ### Log message matching syntax A log line will be ignored if its message contains any of the messages in the "ignore logs" *denylist*. For example, an ignore logs entry with the word `start` will ignore log lines whose messages are "Process started" or "Process failed to start". A limited subset of regular expression syntax can be used to narrow the log lines accepted: * `^` will match the beginning of the message * `$` will match the end of the message * `.*` will match any characters No other regular expression syntax is supported. For example, `^job` will match any log line whose message starts with "job", like "job #123 completed successfully", but it will not ignore any log lines that contain "job" at any other position in the message. Similarly, `completed successfully$` will ignore a log line whose message ends with the words "completed successfully", but it will not ignore any log lines that contain "completed successfully" at any other position in the message. Finally, `^job .* completed successfully$` allows you to ignore log lines that start with "job" and finish with "completed successfully", regardless of what the log message contains in between those words. Log message matching is case-sensitive, meaning that ignoring `job` (lowercase `j`) does not ignore the log message "Job completed" (uppercase `J`). ## Ruby To ignore logs in Ruby, add the following to your AppSignal configuration file. The [`ignore_logs`][ruby ignore_logs] value is an Array of Strings. <CodeGroup> ```ruby Ruby theme={null} Appsignal.configure do |config| config.ignore_logs += [ "^done$", "Task .* completed successfully" ] end ``` ```yaml YAML theme={null} production: ignore_logs: - "^done$" - "Task .* completed successfully" ``` </CodeGroup> ### Read More * Read more about the [Ruby `ignore_logs` config option][ruby ignore_logs]. * [Logging with AppSignal for Ruby](/logging/integrations/ruby). ## Elixir To ignore logs in Elixir, add the following to your AppSignal configuration file. The [`ignore_logs`][elixir ignore_logs] value is a List of Strings. <CodeGroup> ```elixir Elixir theme={null} config :appsignal, :config, ignore_logs: ["^done$", "Task .* completed successfully"] ``` </CodeGroup> ### Read More * Read more about the [Elixir `ignore_logs` config option][elixir ignore_logs]. * [Logging with AppSignal for Elixir](/logging/integrations/elixir). ## Node.js To ignore logs in Node.js, add the following to your AppSignal configuration file. The [`ignoreLogs`][nodejs ignore_logs] value is an Array of Strings. <CodeGroup> ```javascript Node.js theme={null} const { Appsignal } = require("@appsignal/nodejs"); new Appsignal({ // Other config ignoreLogs: ["^done$", "Task .* completed successfully"], }); ``` </CodeGroup> ### Read More * Read more about the [Node.js `ignoreLogs` config option][nodejs ignore_logs]. * [Logging with AppSignal for Node.js](/logging/integrations/nodejs). ## Go To ignore logs in Go applications, configure the [`ignore_logs` config option][go ignore_logs]. See the [Go configuration page](/go/configuration/options) for more information on how to configure OpenTelemetry for Go apps. <CodeGroup> ```go Go theme={null} res := resource.NewWithAttributes( attribute.StringSlice("appsignal.config.ignore_logs", []string{"^done$", "Task .* completed successfully"}), // And other resource attributes ) ``` </CodeGroup> ### Read More * Read more about the [Go `ignore_logs` config option][go ignore_logs]. ## Java To ignore logs in Java applications, configure the [`ignore_logs` config option](/java/configuration/options#option-ignore_logs) using the `OTEL_RESOURCE_ATTRIBUTES` environment variable. The `ignore_logs` value is an array of strings. <CodeGroup> ```bash Bash theme={null} function encode() { echo -n "$@" | sed 's/,/%2C/g' } export OTEL_RESOURCE_ATTRIBUTES="\ appsignal.config.ignore_logs=$(encode "^done$,Task .* completed successfully"),\ ..." ``` </CodeGroup> ### Read More * Read more about the [Java `ignore_logs` config option](/java/configuration/options#option-ignore_logs). ## PHP To ignore logs in PHP applications, configure the [`ignore_logs` config option](/php/configuration/options#option-ignore_logs). The `ignore_logs` value is an array of strings. <CodeGroup> ```php PHP theme={null} return [ 'ignore_logs' => ['^done$', 'Task .* completed successfully'], // ... other options ]; ``` </CodeGroup> ### Read More * Read more about the [PHP `ignore_logs` config option](/php/configuration/options#option-ignore_logs). [elixir ignore_logs]: /elixir/configuration/options.html#option-ignore_logs [nodejs ignore_logs]: /nodejs/3.x/configuration/options.html#option-ignorelogs [ruby ignore_logs]: /ruby/configuration/options.html#option-ignore_logs [go ignore_logs]: /go/configuration/options.html#option-ignore_logs # Ignore Namespaces Source: https://docs.appsignal.com/guides/filter-data/ignore-namespaces In a previous guide, we walked through the steps needed to [set up custom namespaces](/guides/namespaces) in your application. You can use these namespaces to group parts of an application together, but you can also use them to ignore these namespaces entirely. This could be a good alternative to ignoring many [individual actions](/guides/filter-data/ignore-actions). <Tip> Ignoring namespaces will **ignore error and performance data** from all actions in namespaces. AppSignal will still report [custom metrics data](/metrics/custom) recorded in any of the namespace actions. </Tip> ## Ignoring namespaces Namespaces can be ignored by customizing your application's AppSignal integration configuration. The "ignore namespaces" configuration option will allow you to configure a denylist of namespaces. Any namespaces in this list will be ignored, meaning the data from these actions will not be sent to the AppSignal servers and will not count towards your [organization's billing plan](https://www.appsignal.com/plans). The "ignore namespaces" config option is configured differently per integration language. See the list of integrations below for the one your app uses: * [Ruby](#ruby) * [Elixir](#elixir) * [Node.js](#nodejs) * [Python](#python) * [Go](#go) * [Java](#java) * [PHP](#php) <Tip> If you're unsure what namespaces you need to configure in your application's AppSignal configuration, you can use the namespaces filtering dropdown on AppSignal.com and copy those namespaces into your AppSignal configuration. </Tip> ## Ruby To ignore namespaces in Ruby, add the following to your AppSignal configuration file. The [`ignore_namespaces`][ruby ignore_namespaces] value is an Array of Strings. <CodeGroup> ```ruby Ruby theme={null} Appsignal.configure do |config| config.ignore_namespaces += [ "http_request", # "web" namespace on AppSignal "background_job", # "background" namespace on AppSignal "admin", "private" ] end ``` ```yaml YAML theme={null} production: ignore_namespaces: - "http_request" # "web" namespace on AppSignal - "background_job" # "background" namespace on AppSignal - "admin" - "private" ``` </CodeGroup> For more information about this config option, see the [`ignore_namespaces` config option][ruby ignore_namespaces] documentation. ## Elixir To ignore namespaces in Elixir, add the following to your AppSignal configuration file. The [`ignore_namespaces`][elixir ignore_namespaces] value is a List of Strings. <CodeGroup> ```elixir Elixir theme={null} import Config config :appsignal, :config, ignore_namespaces: [ "http_request", # "web" namespace on AppSignal "background_job", # "background" namespace on AppSignal "admin", "private" ] ``` </CodeGroup> For more information about this config option, see the [`ignore_namespaces` config option][elixir ignore_namespaces] documentation. ## Node.js To ignore namespaces in Node.js, add the following to your AppSignal configuration file. The [`ignoreNamespaces`][nodejs ignore_namespaces] value is an Array of Strings. <CodeGroup> ```javascript Node.js theme={null} const { Appsignal } = require("@appsignal/nodejs"); new Appsignal({ // Other config ignoreNamespaces: ["web", "background", "admin", "private"], }); ``` </CodeGroup> For more information about this config option, see the [`ignoreNamespaces` config option][nodejs ignore_namespaces] documentation. ## Python To ignore namespaces in Python, add the following to your AppSignal configuration file. The [`ignore_namespaces`][python ignore_namespaces] value is a list of strings. <CodeGroup> ```python Python theme={null} from appsignal import Appsignal appsignal = Appsignal( # Other config ignore_namespaces=["web", "background", "admin", "private"] ) ``` </CodeGroup> For more information about this config option, see the [`ignore_namespaces` config option][python ignore_namespaces] documentation. ## Go To ignore namespaces in Go applications, add the following to your AppSignal configuration file. The [`ignore_namespaces`][go ignore_namespaces] value is a slice of strings. <CodeGroup> ```go Go theme={null} res := resource.NewWithAttributes( attribute.StringSlice("appsignal.config.ignore_namespaces", []string{"admin", "secret"}), // And other resource attributes ) ``` </CodeGroup> For more information about this config option, configure the [`ignore_namespaces` config option][go ignore_namespaces]. ## Java To ignore namespaces in Java applications, configure the [`ignore_namespaces` config option](/java/configuration/options#option-ignore_namespaces) using the `OTEL_RESOURCE_ATTRIBUTES` environment variable. <CodeGroup> ```bash Bash theme={null} function encode() { echo -n "$@" | sed 's/,/%2C/g' } export OTEL_RESOURCE_ATTRIBUTES="\ appsignal.config.ignore_namespaces=$(encode "admin,secret"),\ ..." ``` </CodeGroup> For more information about this config option, see the [`ignore_namespaces` config option](/java/configuration/options#option-ignore_namespaces) documentation. ## PHP To ignore namespaces in PHP applications, configure the [`ignore_namespaces` config option](/php/configuration/options#option-ignore_namespaces). <CodeGroup> ```php PHP theme={null} return [ 'ignore_namespaces' => ['admin', 'secret'], // ... other options ]; ``` </CodeGroup> For more information about this config option, see the [`ignore_namespaces` config option](/php/configuration/options#option-ignore_namespaces) documentation. [elixir ignore_namespaces]: /elixir/configuration/options.html#option-ignore_namespaces [nodejs ignore_namespaces]: /nodejs/3.x/configuration/options.html#option-ignoreNamespaces [notifications]: /application/notification-settings.html [ruby ignore_namespaces]: /ruby/configuration/options.html#option-ignore_namespaces [python ignore_namespaces]: /python/configuration/options.html#option-ignore_namespaces [go ignore_namespaces]: /go/configuration/options.html#option-ignore_namespaces # Add additional OpenTelemetry Instrumentation Source: https://docs.appsignal.com/guides/instrumentation/additional-opentelemetry-instrumentation OpenTelemetry provides extensive instrumentation for many popular libraries and frameworks. During the installation of AppSignal and OpenTelemetry, you may have installed some instrumentation packages already, but you may need to add additional instrumentation packages to monitor specific libraries your application uses. This guide explains how to identify, install, and configure additional OpenTelemetry instrumentation packages for better observability coverage. ## Why Add Additional Instrumentation? Your application might use libraries that aren't covered by the instrumentation packages you installed during setup, such as: * Database drivers * HTTP client libraries * Message queue systems * Custom or niche libraries Adding instrumentation for these libraries provides a more complete monitoring setup for all components of your application. ## General Steps This section describes the steps that are needed for most languages to instrument additional library. Check the [Language-Specific Instructions](#language-specific-instructions) section for language specific steps. ### 1. Identify Libraries to Instrument First, determine which libraries your application uses that you'd like to monitor. Common candidates include: * Database clients (MySQL, PostgreSQL, MongoDB, Redis) * HTTP clients * Message queues (RabbitMQ, Kafka, SQS) * Template engines ### 2. Find Instrumentation Packages Look for instrumentation packages in this order of preference: 1. **Official OpenTelemetry packages** - Maintained by the OpenTelemetry community 2. **OpenTelemetry contrib packages** - Community-contributed instrumentation 3. **Third-party packages** - Ensure you trust the maintainer and review the code Check the [OpenTelemetry Registry](https://opentelemetry.io/ecosystem/registry/) for available instrumentation packages. Note that some libraries may include OpenTelemetry instrumentation on their own and no further setup is needed. ### 3. Install the Package Once you've found a relevant instrumentation package, install the instrumentation package using your language's package manager. For example: <CodeGroup> ```sh Go theme={null} go get go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp ``` ```sh PHP theme={null} composer require open-telemetry/opentelemetry-auto-guzzle ``` </CodeGroup> ### 4. Initialize the Instrumentation Depending on the language and SDK instrumentation method, instrumentation packages may require initialization in your application's startup code. This typically involves: * Importing the instrumentation package * Calling an initialization function * Configuring any package-specific options For some languages, like PHP and Java using auto instrumentations, this step is not necessary. It will automatically set up the instrumentation, unless instructed otherwise. ### 5. Check Incoming Data After installation, verify that the instrumentation is working: * Check that new spans about the instrumented library appear in your traces reported to AppSignal.com. * Confirm metrics about the instrumented library are being reported to AppSignal.com. * Test error scenarios to ensure errors are reported. ## Language-Specific Instructions For detailed instructions on adding instrumentation packages for specific languages: * [Go Instrumentations](/go/instrumentations) * [Java Instrumentations](/java/instrumentations) * [PHP Instrumentations](/php/instrumentations) ## Troubleshooting ### Common Issues * **Missing traces**: Ensure the instrumentation is initialized before the library is used. * **Incomplete data**: Check if the instrumentation package supports your library version. * **Duplicate spans**: Avoid instrumenting the same library multiple times. ### Getting Help If you encounter issues: 1. Check the instrumentation package documentation 2. Contact [AppSignal support](mailto:support@appsignal.com) for assistance # Link Traces with Logs Source: https://docs.appsignal.com/guides/linking-traces-with-logs Linking traces with [logs](/logging) allows you to correlate error incidents and traces with log messages, making it easier to debug issues by viewing relevant logs directly alongside your traces. By adding an identifier to both your traces and logs, you can navigate between them in the AppSignal interface. ## How It Works To link traces with logs, you need to add the same identifier to both, such as `request_id` or `trace_id`. This will be set up automatically in most cases, but when it's not make sure the following identifiers are set. 1. Add a request or trace identifier to your trace as an AppSignal tag or OpenTelemetry attribute. 2. Add the same identifier to your logs as a log attribute. When AppSignal receives traces and logs with matching identifiers, it can correlate them, allowing you to view related logs when inspecting a trace sample. ## Choosing an Identifier You can use any of the following identifiers to link traces and logs: * **`request_id`** - A unique identifier for each HTTP request (common in web frameworks). * **`trace_id`** - The AppSignal or OpenTelemetry trace ID. Many web frameworks automatically generate a `request_id` for each request, making it a convenient choice. For OpenTelemetry-based integrations, you can use the trace ID directly. ## Linking Application Logs Report logs from your application by [setting up logging](/logging/integrations) using the AppSignal packages or OpenTelemetry SDK. Most framework configuration will already have `request_id` or `trace_id` tags set up. If no relevant logs are detected, follow the [logging set up instructions](/logging/integrations) for the framework your application uses or report the identifier manually as a trace tag and log attribute. ## Viewing Linked Logs Once you've configured your application to link traces with logs, you can view related logs directly in the AppSignal interface: 1. Navigate to a performance trace sample or error incident. 2. Look for the related logs block, which will link to the relevant log messages. 3. Use the logs to gain additional context about what happened during the request. This correlation makes debugging faster, as you can quickly find the relevant trace and logs. ## Next Steps * Set up [log reporting](/logging) to send your application logs to AppSignal. * Learn more about [adding tags](/guides/tagging) to your traces. # Grouping with Namespaces Source: https://docs.appsignal.com/guides/namespaces Namespaces are a way to group error incidents, performance incidents and metrics from actions. AppSignal uses three [namespaces] by default: * `web` for web requests * `frontend` for Front-end JavaScript * `background` for background jobs Applications can have any number of namespaces, for example, you could have a separate namespace for your application's administration panel, API or scheduled tasks. This guide will go through the steps needed to report actions in custom namespaces. <Tip> Want to know more about what namespaces can be used for? Check out this list: [What Can You Do With Namespaces?](/application/namespaces#what-can-you-do-with-namespaces) </Tip> <Frame> <img alt="App Graphs Namespaces" /> </Frame> ## Configuring Namespaces Namespaces are defined by your application's code. With small helpers, you can customize the namespace of an action. This guide will teach you how to split requests up into different namespaces. For this guide, we'll create an "admin" and a "critical" namespace for background jobs. <Tip> Namespace names may only contain letters (a-z) and underscores <br /> We do not recommend having more than **15** namespaces per application. </Tip> #### Configurations per Language * [Ruby](#ruby) * [Elixir](#elixir) * [Node.js](#nodejs) * [Python](#python) * [Front-end JavaScript](#front-end-javascript) * [Go](#go) * [Java](#java) * [PHP](#php) ### Ruby In Rails we can use the `before_action` callback to call a method before a request is handled. In the code example below, we've created a `before_action` that calls the `set_appsignal_namespace` method. In this method we call the [`Appsignal.set_namespace` helper method][ruby helper] to configure "admin" as the namespace for this request. This also works if other controllers are subclasses of the `AdminController`. <CodeGroup> ```ruby Ruby theme={null} # In a Rails controller # app/controllers/admin_controller.rb class AdminController < ApplicationController before_action :set_appsignal_namespace def set_appsignal_namespace # Configures all actions in this controller to report # in the "admin" namespace Appsignal.set_namespace("admin") end # Any other controller actions end ``` </CodeGroup> Next we'll define the namespace of code executed by our application's Sidekiq background workers. To correctly namespace errors triggered in our background worker, we must define the namespace before any other code runs. In the example Sidekiq worker code below, we do this immediately in the perform method on line 7. <CodeGroup> ```ruby Ruby theme={null} # In a Sidekiq worker # app/workers/critical_worker.rb class CriticalWorker include Sidekiq::Worker def perform # Configures this worker's jobs to report in the "critical" namespace Appsignal.set_namespace("critical") # The actual worker code end end ``` </CodeGroup> It's also possible to configure the namespace when creating a transaction using the [`Appsignal.monitor`](https://rubydoc.info/gems/appsignal/Appsignal/Helpers/Instrumentation#monitor-instance_method) helper. It accepts the namespace as a keyword argument. <CodeGroup> ```ruby Ruby theme={null} # When creating a new transaction Appsignal.monitor(namespace: "admin") do # Your code to instrument end ``` </CodeGroup> For transactions that have already been created, you can use the `set_namespace` method to configure the transaction's namespace, like in the example below: <CodeGroup> ```ruby Ruby theme={null} # When changing the namespace later on for a transaction transaction.set_namespace("slow_admin") ``` </CodeGroup> ##### A note on helper location The `set_namespace` helpers used in this guide can be called in any action that is part of an AppSignal sample. We recommend calling this as early in the request or background job as possible, so the transaction is configured with the given namespace before any error occurs. Otherwise, if an error occurs, or anything else that stops the process, the transaction is sent to AppSignal before the `set_namespace` helper is called, and the sample is reported under the default namespace instead. #### Read More * [`Appsignal.set_namespace` helper method documentation][ruby helper] ### Elixir In Phoenix controllers we use a `plug` to call a function before the request is handled by Phoenix. In the code example below we use `plug` to call the `set_appsignal_namespace` function (line 5). In this function we call the [`Appsignal.Span.set_namespace` helper][elixir helper] to configure the namespace for this request (line 10). <CodeGroup> ```elixir Elixir theme={null} # In a Phoenix controller defmodule AppsignalPhoenixExampleWeb.AdminController do use AppsignalPhoenixExampleWeb, :controller plug :set_appsignal_namespace defp set_appsignal_namespace(conn, _params) do # Configures all actions in this controller to report # in the "admin" namespace Appsignal.Span.set_namespace(Appsignal.Tracer.root_span(), "admin") conn end # ... end ``` </CodeGroup> Next we'll configure the namespace for a background job. To catch any errors from within the job within the desired namespace, `Appsignal.Span.set_namespace` must be called at the beginning of the function before any other code, like on line 4 of the below code example: <CodeGroup> ```elixir Elixir theme={null} defmodule MyApp.CriticalJob do def run do # Configures this worker's jobs to report in the "critical" namespace Appsignal.Span.set_namespace(Appsignal.Tracer.root_span(), "critical") # The actual worker code end end ``` </CodeGroup> It's also possible to configure the namespace when creating a transaction. Please see the documentation for [decorators][elixir namespace_decorator] or [instrumentation helpers][elixir namespace_helper] for more information on how to configure namespaces. #### A note on helper location The `set_namespace` helpers used in this guide can be called in any action that starts an AppSignal transaction. We recommend calling this as early in the request or background job as possible, so the transaction is configured with the given namespace before any error occurs. Otherwise, if an error occursβ€”or anything else that stops the processβ€”the transaction is sent to AppSignal before the `set_namespace` code is called and it is reported under the default namespace instead. #### Read More * [`Appsignal.Span.set_namespace` Helper Method Documentation][elixir helper] * [Elixir Namespace Decorator][elixir namespace_decorator] * [Elixir Namespace Instrumentation Helper][elixir namespace_helper] ### Node.js In Node.js applications, AppSignal works with OpenTelemetry, which uses spans to track metadata, such as which namespace a span belongs to. Use the `setNamespace` helper function as sampled below to set the namespace for the active span's trace. <CodeGroup> ```javascript Node.js theme={null} import { setNamespace } from "@appsignal/nodejs"; setNamespace("custom-namespace"); ``` </CodeGroup> [Read more about how spans work in Node.js](/nodejs/3.x/instrumentation/instrumentation). ### PHP In PHP applications, AppSignal works with OpenTelemetry, which uses spans to track metadata, such as which namespace a span belongs to. Use the `Appsignal::setNamespace` helper method to set the namespace for the active span's trace. <CodeGroup> ```php PHP theme={null} Appsignal::setNamespace("admin"); ``` </CodeGroup> If you call this helper multiple times within a single trace, AppSignal uses the call whose span has the newest timestamp. [Read more about how custom instrumentation works in PHP][php custom instrumentation]. [php custom instrumentation]: /php/instrumentation.html ### Python In Python applications, AppSignal works with OpenTelemetry, which uses spans to track metadata, such as which namespace a span belongs to. Use the `set_namespace` helper function as sampled below to set the namespace for the active span's trace. <CodeGroup> ```python Python theme={null} from appsignal import set_namespace set_namespace("custom-namespace") ``` </CodeGroup> [Read more about how spans work in Python](/python/instrumentation/instrumentation). ### Front-end JavaScript In Front-end JavaScript applications AppSignal works with spans to track metadata such as a span's namespace. <Tip> Unlike Ruby, Node.js, PHP, and Python, the Front-end JavaScript API does not have a global `setNamespace` / `set_namespace` helper. Instead, like Elixir, Go, and Java, you set the namespace directly on a span. </Tip> When creating this span, call `setNamespace` with a `String` value of the desired namespace name, as demonstrated in the below example: <CodeGroup> ```javascript JavaScript theme={null} const span = appsignal.createSpan(); span.setNamespace("admin"); // a custom namespace for this span (defaults to `frontend`) ``` </CodeGroup> [Read more about how spans work in Front-End JavaScript](/front-end/span). ### Go In Go applications, AppSignal works with OpenTelemetry, which uses spans to track metadata, such as which namespace a span belongs to. On any span in the trace, set a `appsignal.namespace` attribute with a String value of the new namespace. <CodeGroup> ```go Go theme={null} span.SetAttributes(attribute.String("appsignal.namespace", "admin")) ``` </CodeGroup> Please see the [Go custom instrumentation docs][go custom instrumentation] on how to fetch a span or create a new one. If multiple attributes with the `appsignal.namespace` attribute are found, the span with the newest timestamp is leading. [Read more about how custom instrumentation works in Go][go custom instrumentation]. [go custom instrumentation]: /go/custom-instrumentation.html ### Java In Java applications, AppSignal works with OpenTelemetry, which uses spans to track metadata, such as which namespace a span belongs to. On any span in the trace, set a `appsignal.namespace` attribute with a String value of the new namespace. <CodeGroup> ```java Java theme={null} span.setAttribute("appsignal.namespace", "admin"); ``` </CodeGroup> Please see the [Java custom instrumentation docs][java custom instrumentation] on how to fetch a span or create a new one. If multiple attributes with the `appsignal.namespace` attribute are found, the span with the newest timestamp is leading. [Read more about how custom instrumentation works in Java][java custom instrumentation]. [java custom instrumentation]: /java/custom-instrumentation.html ## Deploy When your application is configured with its new namespace helpers, commit your changes and deploy the app. When the app starts/restarts, AppSignal will report actions under their new namespace πŸ₯³! <Tip> Data from old deploys will remain grouped by their original namespace. Only newly reported actions will be grouped by their new namespaces. </Tip> Are namespaces not being reported correctly? Don't panic, [give us a shout][contact] and we will help you out! ## Further Reading * [Filtering App Data][filtering] * [Namespaces][namespaces] * [Ignoring Namespaces][ignoring namespaces] [contact]: mailto:support@appsignal.com [elixir helper]: https://hexdocs.pm/appsignal/Appsignal.Span.html?#set_namespace/2 [elixir namespace_decorator]: /elixir/instrumentation/instrumentation.html#decorator-namespaces [elixir namespace_helper]: /elixir/instrumentation/instrumentation.html#helper-namespaces [filtering]: /guides/filter-data/ [ignoring namespaces]: /guides/filter-data/ignore-namespaces.html [namespaces]: /application/namespaces.html [ruby helper]: https://gemdocs.org/gems/appsignal/3.4.0/Appsignal/Transaction.html#initialize-instance_method [tagging]: /guides/tagging.html # Add a New Application Source: https://docs.appsignal.com/guides/new-application Getting your application up-and-running with AppSignal is easy and shouldn't take more than ten minutes. This guide will take you through all necessary steps to get your application integrated with AppSignal. ## Requirements To make setting up AppSignal a breeze, we've created an installation wizard to guide you through each installation step, so be sure to [sign in](https://appsignal.com/users/sign_in) to your AppSignal account before you start this guide. Don't forget to check the [Supported Operating Systems](/support/operating-systems) documentation to make sure your system is compatible with AppSignal. ## Adding Your Application To get a new app running on AppSignal and access the installation wizard, you can click the "Add app" button on the Applications overview page, or if you are signed in, you can use [this link](https://appsignal.com/redirect-to/organization?to=sites/new) to start the installation wizard. <img alt="Add app" /> The wizard will first ask you what your application's language is. We currently support Ruby, Elixir & Node.js for error and performance monitoring and JavaScript for front-end error monitoring. Next, the wizard will tell you how to install AppSignal. This part of the process will vary depending on your programming language. ## Installing AppSignal Some language integrations and support for libraries require some manual steps to get set up. Please see our language-specific installation instructions (listed below) for more information. * [Ruby Installation Instructions](/ruby/installation/) * [Elixir Installation Instructions](/elixir/installation/) * [Node.js Installation Instructions](/nodejs/3.x/installation/) * [Python Installation Instructions](/python/installation/) * [Front-End JavaScript Installation Instructions](/front-end/installation) * [Go Installation Instructions](/go/installation) * [Java Installation Instructions](/java/installation) * [PHP Installation Instructions](/php/installation) AppSignal will only detect and register new Ruby, Elixir, Node.js and Python applications once it receives data from your application. This data is sent automatically if you use the AppSignal installation tool for your application's language. For other languages, start the app, make some requests to it, or trigger some other script, to report some data to AppSignal. Do you intend to install AppSignal manually in your Ruby, Elixir, Node.js or Python application? To send data to AppSignal, you need to use the demo command line tool linked below or start your application and perform some requests/jobs to send data to AppSignal. * [Ruby Command Line Demo](/ruby/command-line/demo) * [Elixir Command Line Demo](/elixir/command-line/demo) * [Node.js Command Line Demo](/nodejs/3.x/command-line/demo) * [Python Command Line Demo](/python/command-line/demo) ## Completing Your Installation Once installed, the wizard will check that the installation is working and that AppSignal can receive data from your application. On the rare occasion that the wizard cannot verify if the installation has succeeded, don't panic; [we're here to help](mailto:support@appsignal.com). Once AppSignal is successfully installed, you can commit and deploy the changes you've made to your application AppSignal will start receiving data, and you're good to go! Now it's time to start configuring your application! # Find Slow Database Queries Source: https://docs.appsignal.com/guides/slow-queries Requests and background jobs can be slow for various reasons, but a common cause are slow database queries. Large tables and missing indexes may cause database queries to take longer than needed, increasing the amount of time that your application's users have to wait. AppSignal's Slow Queries feature makes it easier to find an application's slowest queries, to help you decide which queries require optimization. You can view your application's slow queries [here][slow queries]. ## Finding Slow Queries for Ruby, Elixir, Node.js and Python The type of events that can be found in the Slow Queries page are listed below. * Elasticsearch * MongoDB * MySQL * PostgreSQL * Redis * SQLite Events may be grouped under the ORM (Object-relational mapping) event group name for some integrations. ## Finding Slow Queries for OpenTelemetry For OpenTelemetry-based integrations, we look for spans with a certain set of attributes listed below. For the **query body**, we look for the following attributes in order: * `db.query.text` * `db.query.statement` * `db.stored_procedure.name` One of these attributes must be present, and not empty. For the **system name**, we look for the following attributes in order: * `db.system.name` * `db.system` If neither is present, the system will be shown as `Unknown`. If your application is reporting queries in a differently named attribute, or you would like to customize the recognized attributes, please [give us feedback](mailto:support@appsignal.com). ## Sorting Queries By default the slow query list is sorted by impact: the queries that take up the most time either by duration of queries or by how often they are performed. It is also possible to sort this table by "Throughput", how often the query has been recorded, and "Mean", the mean duration of the queries. ## Query Details <img alt="Query details screenshot" /> You can click on a query to gain the following insights: * Full query with optional event title for more context * The database query event summary: * Mean duration of query * Throughput, how often the query was recorded * The impact of the query in percentage of all database queries in the selected timeframe. * Response time graph * Throughput graph * Actions and performance measurements in which the event occurred: * You can go directly to actions and performance measurements in which the event was recorded to view the impact per request/background job in the sample event timeline. [slow queries]: https://appsignal.com/redirect-to/app?to=improve/queries # Find Slow HTTP requests Source: https://docs.appsignal.com/guides/slow-requests Requests and background jobs can be slow for various reasons, but a common cause are slow HTTP requests to external services. This can include sending emails, fetching data from third-party APIs, and other HTTP requests. AppSignal's Slow Requests feature makes it easier to find an application's slowest HTTP requests, to help you decide which requests require optimization or should be moved to asynchronous processes. View your application's [Slow Requests][slow requests]. ## Finding Slow Requests for Ruby, Elixir, Node.js and Python The type of [event groups](/api/event-names) that can be found in the Slow Requests page are listed below. * faraday * grpc * http * http\_rb * net\_http * excon * request * requests * service * finch * tesla * fetch Events may be grouped under the HTTP library's event group name for some integrations. If your application is reporting HTTP requests in a differently named attribute, or you would like to customize the recognized attributes, please [give us feedback](mailto:support@appsignal.com). ## Finding Slow Requests for OpenTelemetry For OpenTelemetry-based integrations, we look for spans with a certain set of attributes listed below. We follow the [OpenTelemetry HTTP client span specification](https://opentelemetry.io/docs/specs/semconv/http/http-spans/#http-client-span). For the **HTTP request server name**, we look for the following attributes in order: * `server.address` * `net.peer.name` * `http.server_name` One of these attributes must be present, and not empty. For the **HTTP request method**, we look for the following attributes in order: * `http.request.method` * `http.method` If neither is present, the system will be shown as `Unknown`. If your application is reporting HTTP requests in a differently named attribute, or you would like to customize the recognized attributes, please [give us feedback](mailto:support@appsignal.com). ## Sorting HTTP requests By default the slow HTTP requests list is sorted by impact: the requests that take up the most time either by duration or by how often they are performed. It is also possible to sort this table by "Throughput", how often the request has been recorded, and "Mean", the mean duration of the requests. ## HTTP Request Details <img alt="Query details screenshot" /> You can click on an HTTP request to gain the following insights: * Domain that was contacted * Which HTTP request method was used * The HTTP request event summary: * Mean duration of the HTTP request * Throughput, how often the HTTP request was recorded * The impact of the HTTP request in percentage of all HTTP requests in the selected timeframe. * Response time graph * Throughput graph * Actions and performance measurements in which the event occurred: * You can go directly to actions and performance measurements in which the event was recorded to view the impact per request/background job in the sample event timeline. [slow requests]: https://appsignal.com/redirect-to/app?to=improve/requests # Add Tags to a Request Source: https://docs.appsignal.com/guides/tagging You can use tagging to supply extra context on errors and performance incidents. Tagging can help to add information that is not already part of a request, such as the session data, headers, environment data, or parameters. Tags can also be used to filter on samples within an incident to find all errors for a specific user or slow pages for a particular locale. You can set tags wherever the current transaction or span is accessible. We recommend calling it before your application code runs in a request, such as a callback. You can see what tags apply to a sample on the [Error and Performance](https://appsignal.com/redirect-to/app?to=performance) incident page. Using [Link Templates](/application/link-templates) it's possible to add links to your application with tag data, such as the admin panel for the signed-in user. You can see this in practice in the below screenshot, with the `Link 1` and `Link 2` tags. <img alt="Tag a request" /> <Warning> πŸ” Do not send <strong>Personal Identifiable Information (PII)</strong> to AppSignal. Filter PII (e.g., names, emails) and use an ID, hash, or pseudonymized identifier instead. <br /> <br /> Use [Link Templates](https://docs.appsignal.com/application/link-templates) to link them back in your app. </Warning> ## Ruby With the [AppSignal for Ruby](/ruby) gem, use the `Appsignal.add_tags` helper methods to add tags to error and performance samples. On Ruby gem version 3 and older, use the `Appsignal.set_tags` helper. You can use `Appsignal.add_tags` wherever an active transaction is accessible, we recommend calling it before your application code runs in the request, such as in a `before_action` using Rails. <CodeGroup> ```ruby Ruby theme={null} before_action do Appsignal.add_tags( :user_id => current_user.id, :stripe_customer_id => stripe_customer_id, :locale => I18n.locale, :default_locale => I18n.default_locale ) end ``` </CodeGroup> ### Default tags <Compatibility /> You can configure tags that will be added to all transactions using the [`default_tags` config option](/ruby/configuration/options#option-default_tags). These tags are applied automatically to every transaction. Transaction-specific tags set with `Appsignal.add_tags` will override default tags with the same key. <CodeGroup> ```ruby Ruby theme={null} Appsignal.configure do |config| config.default_tags = { "region" => "europe", "shard" => "shard-1" } end ``` ```yaml YAML theme={null} default: &defaults default_tags: region: europe shard: shard-1 ``` ```bash Shell theme={null} export APPSIGNAL_DEFAULT_TAGS="region=europe,shard=shard-1" ``` </CodeGroup> ### Limitations Tags that do not meet these limitations are dropped without warning. * The tag key must be a String or Symbol. * The tagged value must be a String, Symbol, Integer or Boolean (true/false). * Boolean values are supported in Ruby gem 3.11 and newer. * The length of the tag value must be less than 256 characters. * Nested hash values are not supported for tags, please use [custom data](/guides/custom-data/custom-data) instead. <CodeGroup> ```ruby Ruby theme={null} # Unsupported: hash value type is not supported Appsignal.add_tags( :i18n => { :locale => I18n.locale, :default_locale => I18n.default_locale } ) ``` </CodeGroup> ## Elixir Use the [`Appsignal.Span.set_sample_data`](https://hexdocs.pm/appsignal/Appsignal.Span.html#set_sample_data/2) function to supply extra context on errors and performance samples. Use the `"tags"` sample key for the function to add tags to the span. <CodeGroup> ```elixir Elixir theme={null} Appsignal.Span.set_sample_data( Appsignal.Tracer.root_span, "tags", %{ locale: "en", user_id: user_id, stripe_customer_id: stripe_customer_id, locale: locale, default_locale: default_locale } ) ``` </CodeGroup> ### Last call is leading The `set_sample_data` helper can be called multiple times, but only the last value will be retained. When the code is run below: <CodeGroup> ```elixir Elixir theme={null} Appsignal.Span.set_sample_data(Appsignal.Tracer.root_span, "tags", %{locale: "en"}) Appsignal.Span.set_sample_data(Appsignal.Tracer.root_span, "tags", %{user: "bob"}) Appsignal.Span.set_sample_data(Appsignal.Tracer.root_span, "tags", %{locale: "de"}) ``` </CodeGroup> it will result in the following tags being stored: <CodeGroup> ```elixir Elixir theme={null} %{ locale: "de" } ``` </CodeGroup> ### Setting sample data on a span To add sample data to a span as soon as it's created, add a `custom_on_create_fun`: <CodeGroup> ```elixir Elixir theme={null} defmodule MyApp.Appsignal do def custom_on_create_fun(_span) do Appsignal.Span.set_sample_data(Appsignal.Tracer.root_span, "tags", %{"locale": "en"}) end end ``` </CodeGroup> Then, add it to your app's configuration: <CodeGroup> ```elixir Elixir theme={null} # config/config.exs config :appsignal, custom_on_create_fun: &MyApp.Appsignal.custom_on_create_fun/1 ``` </CodeGroup> The `custom_on_create_fun` requires AppSignal for Elixir version 2.8.3 or higher. ### Limitations Tags that do not meet these limitations are dropped without warning. * The tag key must be a `String` or `Atom`. * The tagged value must be a `String`, `Atom` or `Integer`. * The length of the tag value must be less than 256 characters. * Nested map values are not supported for tags, please use [custom data](/guides/custom-data/custom-data) instead. <CodeGroup> ```elixir Elixir theme={null} # Unsupported: map value type is not supported Appsignal.Span.set_sample_data( Appsignal.Tracer.root_span, "tags", %{ i18n: %{ locale: "en_GB", default_locale: "en_US" } } ) ``` </CodeGroup> ## Node.js Import the `setTag` helper function to add tags to spans for errors and performance samples. <CodeGroup> ```javascript Node.js theme={null} import { setTag } from "@appsignal/nodejs"; setTag("user_id", user_id); setTag("stripe_customer_id", stripe_customer_id); setTag("locale", locale); setTag("default_locale", default_locale); ``` </CodeGroup> ### Limitations Tags that do not meet these limitations are dropped without warning. * The tag key must be a `String`. * The tagged value must be a `String`, `Number` or `Boolean`. * The length of the tag value must be less than 256 characters. * Nested object values are not supported for tags, please use the [`setCustomData`](/guides/custom-data/custom-data) helper function instead. <CodeGroup> ```javascript Node.js theme={null} const tracer = appsignal.tracer(); const span = tracer.currentSpan(); # Unsupported: object value type is not supported span.set("i18n", { locale: "en_GB", default_locale: "en_US" }); ``` </CodeGroup> ## Python Import the `set_tag` helper method to add tags to spans for errors and performance samples. <CodeGroup> ```python Python theme={null} from appsignal import set_tag set_tag("user_id", user_id) set_tag("stripe_customer_id", stripe_customer_id) set_tag("locale", locale) set_tag("default_locale", default_locale) ``` </CodeGroup> ### Limitations Tags that do not meet these limitations are dropped without warning. * The tag key must be a String. * The tagged value must be a String, Integer, Float or Boolean. * The length of the tag value must be less than 256 characters. * Nested object values are not supported for tags, please use the [`set_custom_data`](/guides/custom-data/custom-data) helper function instead. ## Go In a Go app, to add an AppSignal tag to a span on a trace, first fetch the active span or create a new span as described on [our Go custom instrumentation page](/go/custom-instrumentation). Then, set an attribute on the span using the attribute helper that matches the type of the tag value, see also [the tag limitations below](#go-limitations). The span attribute name has the following format: `appsignal.tag.<tag name>`. Replace `<tag name>` with the name of the tag. <CodeGroup> ```go Go theme={null} // Example format span.SetAttributes(attribute.String("appsignal.tag.<tag_name>", "string")) // Supported types span.SetAttributes(attribute.String("appsignal.tag.my_tag_string", "tag value")) span.SetAttributes(attribute.StringSlice("appsignal.tag.my_tag_int64", []string{"abc", "def"})) span.SetAttributes(attribute.Bool("appsignal.tag.my_tag_bool_true", true)) span.SetAttributes(attribute.Bool("appsignal.tag.my_tag_bool_false", false)) span.SetAttributes(attribute.BoolSlice("appsignal.tag.my_tag_bool_slice", []bool{true, false})) span.SetAttributes(attribute.Float64("appsignal.tag.my_tag_float64", 12.34)) span.SetAttributes(attribute.Float64Slice("appsignal.tag.my_tag_float64_slice", []float64{12.34, 56.78})) span.SetAttributes(attribute.Int("appsignal.tag.my_tag_int", 1234)) span.SetAttributes(attribute.IntSlice("appsignal.tag.my_tag_int", []int{1234, 5678})) span.SetAttributes(attribute.Int64("appsignal.tag.my_tag_int64", 1234)) span.SetAttributes(attribute.Int64Slice("appsignal.tag.my_tag_int64_slice", []int64{1234, 5678})) ``` </CodeGroup> ### Limitations Tags that do not meet these limitations are dropped without warning. * The tag key must be a String. * The tagged value must be a String, Integer, Float, Boolean, or a slice of those types. * The length of the tag value must be less than 256 characters. * Array values are flattened to comma separated values. * Nested object values (maps) are not supported for tags. ## Java In a Java app, to add an AppSignal tag to a span on a trace, first fetch the active span or create a new span as described on [our Java custom instrumentation page](/java/custom-instrumentation). Then, set an attribute on the span using the `setAttribute` method. The span attribute name has the following format: `appsignal.tag.<tag name>`. Replace `<tag name>` with the name of the tag. <CodeGroup> ```java Java theme={null} import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.common.AttributeKey; // Get the current span Span span = Span.current(); // Example format span.setAttribute("appsignal.tag.<tag_name>", "string"); // Set tags as span attributes span.setAttribute("appsignal.tag.my_tag_string", "tag value"); span.setAttribute(AttributeKey.stringArrayKey("appsignal.tag.my_tag_string_array"), Arrays.asList("abc", "def")); span.setAttribute("appsignal.tag.my_tag_bool_true", true); span.setAttribute("appsignal.tag.my_tag_bool_false", false); span.setAttribute(AttributeKey.booleanArrayKey("appsignal.tag.my_tag_bool_array"), Arrays.asList(true, false)); span.setAttribute("appsignal.tag.my_tag_float64", 12.34); span.setAttribute(AttributeKey.doubleArrayKey("appsignal.tag.my_tag_float64_array"), Arrays.asList(12.34, 56.78)); span.setAttribute("appsignal.tag.my_tag_int", 1234); span.setAttribute(AttributeKey.longArrayKey("appsignal.tag.my_tag_int_array"), Arrays.asList(1234L, 5678L)); span.setAttribute("appsignal.tag.my_tag_int64", 1234); span.setAttribute(AttributeKey.longArrayKey("appsignal.tag.my_tag_int64_array"), Arrays.asList(1234L, 5678L)); ``` </CodeGroup> ### Limitations Tags that do not meet these limitations are dropped without warning. * The tag key must be a String. * The tagged value must be a String, Integer, Long, Double, or Boolean, or a list of these values. * The length of the tag value must be less than 256 characters. * Array values are flattened to comma separated values. * Nested object values (maps) are not supported for tags. ## PHP In PHP applications, to add an AppSignal tag to a span on a trace, use the `Appsignal::addTags()` helper method. <CodeGroup> ```php PHP theme={null} <?php // Add tags to the current span Appsignal::addTags([ 'my_tag_string' => 'tag value', 'my_tag_string_slice' => ['abc', 'def'], 'my_tag_bool_true' => true, 'my_tag_bool_false' => false, 'my_tag_bool_slice' => [true, false], 'my_tag_float64' => 12.34, 'my_tag_float64_slice' => [12.34, 56.78], 'my_tag_int' => 1234, 'my_tag_int_slice' => [1234, 5678], 'my_tag_int64' => 1234, 'my_tag_int64_slice' => [1234, 5678], ]); ``` </CodeGroup> ### Limitations Tags that do not meet these limitations are dropped without warning. * The tag key must be a String. * The tagged value must be a String, Integer, Float, or Boolean, or a slice of these values. * The length of the tag value must be less than 256 characters. * Array values are flattened to comma separated values. * Nested object values (maps) are not supported for tags. # Attribute distributions Source: https://docs.appsignal.com/guides/tagging/attribute-distributions Attribute distributions can help you get to the source of an error by showing a distribution of errors per tag. <img alt="Screenshot of Attributes Page" /> This can help you show how many errors happened on frontend1 vs frontend2, for example. Or if a specific deploy caused more errors than another deploy. Attribute distributions work by looking at "special" tags in a sample. We extract the values from these special tags and compute the distributions from them. ## Tagging samples You can tag a sample with the following tags to get enriched distributions for them: * `hostname` To show distributions by hosts * `revision` To show distributions per deploy/revision * `country` (For front-end errors) to show which countries experience the most issues * `country_code` (For front-end errors) to show which countries experience the most issues * `browser` (For front-end errors) to show which browser is the cause The following tags are also accepted, but not enriched. They are shown as tagged: * `company` * `slug` * `user_id` * `account_id` * `customer_id` * `visitor_id` * `client_id` * `group_id` * `site_id` Most of the enriched tags are applied to samples automatically; our agent sets the `hostname` tag and if you use deploy tracking with ENV vars, we use the `revision` tag from that. For front-end errors we extract the `country` from the IP address that sent the error, as well as the `browser` tag. Tags we don't set automatically are the `user_id` and `company` tags. You can tag these yourself to get a better sense of which users have experienced an issue. If you'd like to use attributes not in this list, we're happy to add more. Please [contact support](mailto:support@appsignal.com). ## Notes to keep in mind We extract tags from samples, which means in some cases, if an enormous amount of errors are sent in a short timeframe, we don't get every tag from every sample, as these are throttled by our integrations. Tags are stored for the duration of your plan's retention. This can range from seven days to sixty days, depending on your plan. This means distributions can change over time, depending on how many error samples we still have in retention. # Heroku dashboards Source: https://docs.appsignal.com/heroku/dashboards Learn how to set up Heroku Dashboards and what each dashboard means. <Tip> **Tip:** Make sure you have completed the [Heroku setup](/heroku/setup) and have a working Heroku Log Drain (for Cedar generation) or Heroku Telemetry drain (for Fir generation) before continuing with this section. </Tip> These dashboards will be generated automatically as "Magic dashboards", when a Log Drain or Telemetry Drain is set up. No further action is required. Note that in some cases you need a: * [Status code dashboard](#status-code-dashboard) * [Redis dashboard](#redis-dashboard) * [PostgreSQL dashboard](#postgresql-dashboard) ## Status code dashboard <Tip> This dashboard is available only for Heroku Cedar generation applications. </Tip> The status dashboard shows an aggregation of the status codes, returned by Heroku. These a grouped in the main status code categories (2xx, 3xx, 4xx and 5xx). ## Redis dashboard <Tip> For Heroku Cedar generation, Redis metrics are available on premium (or higher plan) instances. For Heroku Fir generation, Redis metrics are available on all instances. </Tip> The Redis dashboard is based on the metrics provided by Heroku. It shows active connections, hit rate, evicted keys and Redis host metrics. **Active Connections**: The number of connections established on the Redis instance. **Redis hit rate**: The ratio of successful reads out of all read operations, rounded to five decimal points. **Redis evicted keys**: The number of evicted keys due to reaching your instance maxmemory limit. **Memory**: Approximate amount of memory used by your Redis processes in kB. This includes shared buffer cache as well as memory for each connection. **Redis server Load average**: Average load on the system over a period of 1 minute. **Redis server I/O**: Number of read/write operations in I/O sizes of 16KB blocks ## PostgreSQL dashboard <Tip> This dashboard is available only for Heroku Postgres Standard and Premium instances. </Tip> The Postgres dashboard is based on the metrics provided by the Heroku platform and it shows database size, connections and index hit rates. **Waiting connections**: Connections waiting for a lock. If there are too many connections waiting, it could point to over-use of connections by not using a connection pool, for example. **Index/Table cache hit rate**: Ratio of index lookups served from a buffer cache. Ideally, this value is always 0.99 or higher. If it drops below 0.99 consistently, you may need to upgrade your database plan or add more RAM. Cache hit rate is a great metric to set an [anomaly detection trigger](/anomaly-detection) on. **Memory usage**: We track both memory used by Postgres and the system itself. Postgres memory includes buffer cache and memory per connection. For multi-tenant plans, system metrics may include other databases and might be misleading. **Load average**: Average system load of the Heroku database server, for more information about how to read load averages, we've written a blog post about it a while ago called: ["Understanding system load and load averages"](https://blog.appsignal.com/2018/03/28/understanding-system-load-and-load-averages.html). **I/O read/write operations**: Number of read/write operations in sizes of 16KB Blocks. Each Postgres plan has a limit on IOPS it can perform ([see the Heroku docs here](https://devcenter.heroku.com/articles/heroku-postgres-production-tier-technical-characterization)), this would be an excellent candidate to set an [anomaly detection trigger](/anomaly-detection) on. For more information about these metrics, you can read more on [the Heroku documentation page](https://devcenter.heroku.com/articles/heroku-postgres-metrics-logs). # Heroku Deploy Markers Source: https://docs.appsignal.com/heroku/deploys Learn how to set up deploy markers for Heroku dyno's for AppSignal using Heroku's logplex system. A deploy marker indicates a change in the deployed version of an application. This can be used to group together occurrences of errors and performance issues within a certain time frame. From when the version was deployed until a newer version was deployed. Deploy markers are also required to enable [backtrace links](/application/backtrace-links) for an app. We normally recommend using the [`revision` config option](/application/markers/deploy-markers) to set the correct revision for a deploy. ## Cedar (Legacy Platform) applications <Note> Make sure a working [Heroku Logplex Log Drain](/heroku/setup) is setup before continuing with this section. </Note> Using Heroku with the [Heroku Labs: Dyno Metadata](https://devcenter.heroku.com/articles/dyno-metadata) enabled will automatically set the `revision` config option to the `HEROKU_SLUG_COMMIT` system environment variable. This will automatically report new deploys when the Heroku app gets deployed. <Note> πŸ“– Read our guide on [how to set up deploy markers](/guides/deploy-markers). </Note> To enable Dyno metadata run: ```bash Bash theme={null} heroku labs:enable runtime-dyno-metadata -a <app_name> ``` replacing `<app_name>` with your app name. And that's it! Deploys will now automatically be tracked by AppSignal. ## Fir applications Currently, deploy markers aren't available for Heroku Fir generation applications. # Heroku host metrics Source: https://docs.appsignal.com/heroku/host-metrics Learn how to set up host metrics for Heroku dyno's for AppSignal using Heroku's logplex system. ## Cedar (Legacy Platform) applications <Note> Make sure a working [Heroku Logplex Log Drain](/heroku/setup) is setup before continuing with this section. </Note> Heroku provides a service to retrieve host metrics from a Dyno through their [Logplex system](https://devcenter.heroku.com/articles/logplex). AppSignal provides an endpoint to read these metrics from your app's logs. This is the only way to receive accurate host metrics in AppSignal for Heroku apps. The AppSignal [host metrics](/metrics/host-metrics) feature does not work reliably on Heroku as it doesn't directly expose runtime metrics for LXC containers in which their Dynos run. Using the normal host metrics collection your Heroku apps will report the host metrics for the parent system on which many Heroku apps run rather than metrics limited to your Dynos. From the Logplex system we're able to receive the following metrics from your apps per dyno: * Load average * Memory total limit * Memory used To setup AppSignal to receive these metrics, please follow the guide below. ### 1. Update the AppSignal integration. First update the Ruby gem to version 2.6.0 or newer. For Elixir, please update to version 1.6.0 or newer of the AppSignal integration. We switched from using the dyno's UUID to the name (e.g. `web.1`), to make sure we can match the metrics we get from the Logplex drain with the data we receive from the integration, please make sure to run `2.6.x` or better. ### 2. Enable host runtime metrics on Heroku The Heroku host [runtime metrics](https://devcenter.heroku.com/articles/log-runtime-metrics) feature will log the host metrics for your dynos at set intervals to your app's log. To enable this feature on your Heroku app, run the following command on your console. ```bash Bash theme={null} heroku labs:enable log-runtime-metrics heroku restart ``` After restarting the app you should see the following appear in your logs every now and then. <CodeGroup> ```bash Bash theme={null} $ heroku logs --tail source=web.1 dyno=heroku.2808254.d97d0ea7-cf3d-411b-b453-d2943a50b456 sample#load_avg_1m=2.46 sample#load_avg_5m=1.06 sample#load_avg_15m=0.99 source=web.1 dyno=heroku.2808254.d97d0ea7-cf3d-411b-b453-d2943a50b456 sample#memory_total=21.00MB sample#memory_rss=21.22MB sample#memory_cache=0.00MB sample#memory_swap=0.00MB sample#memory_pgpgin=348836pages sample#memory_pgpgout=343403pages ``` </CodeGroup> Please see the [Heroku Logplex documentation](https://devcenter.heroku.com/articles/log-runtime-metrics) for more information on how to set this up if you run into problems. After adding the labs feature, host metrics for your app will appear after a few minutes in the ["host metrics" section](https://appsignal.com/redirect-to/app?to=host_metrics). ## Fir applications Heroku Fir platform provides [dyno runtime metrics](https://devcenter.heroku.com/articles/heroku-opentelemetry-signals-and-attributes-reference#dyno-runtime-metrics) through its OpenTelemetry signals that you can configure by following the [Fir setup guide](/heroku/setup#fir-applications). Once you have completed the initial setup, no additional steps are required. Your application's [host metrics](/metrics/host-metrics) will appear in AppSignal in a few minutes. # Heroku Logplex Errors Source: https://docs.appsignal.com/heroku/logplex-errors Learn how to set up Heroku Logplex Errors what the errors mean. <Note> Make sure a working [Heroku Logplex Log Drain](/heroku/setup) is setup before continuing with this section. </Note> AppSignal will automatically extract Heroku errors from the Logplex data when a Log Drain is setup, no further action is required. These errors behave like application errors and will produce incidents and samples. These errors will show up under a dedicated "heroku" namespace on AppSignal. <img alt="Screenshot of AppSignal incident list with a Heroku error" /> Because the errors are generated from Log lines, the information available is limited, we only get the Error name/code, metadata such as request\_id, path, method (GET/POST) etc, which will be available in the "Overview" section of the sample. These values are also available to filter samples by. The error code is determined by Heroku, for a full list of error codes, see the [Heroku errors documentation](https://devcenter.heroku.com/articles/error-codes). You'll receive notifications for these errors when notifiers are setup. If you do not wish to receive notifications for these errors, it's recommended to setup [Namespace default notification settings](/application/notification-settings). # Setup Source: https://docs.appsignal.com/heroku/setup Learn how to set up Heroku for AppSignal. AppSignal's Heroku metrics, error reporting, and dashboards are available for Cedar (Legacy Platform) and Fir generation applications and can be configured in just a few steps. ## Cedar (Legacy Platform) applications For [Heroku Cedar](https://devcenter.heroku.com/articles/generations#cedar) applications you can configure AppSignal's metrics, error reporting and dashboards with a [Logplex Log Drain](https://devcenter.heroku.com/articles/logplex). If you also want to access and manage your Heroku logs in AppSignal, you should instead configure the [Heroku Log drain for AppSignal Logging](/logging/platforms/heroku). You only have to set up this log drain once per application and it will provide data for all features such as [Heroku platform errors](/heroku/logplex-errors), dashboards and host metrics. <Warning> This Heroku log drain setup will send only metrics to AppSignal. AppSignal will receive logs from Heroku, but they will be discarded. To send both metrics and logs to AppSignal, follow the Heroku log drain setup [in our Logging documentation](/logging/platforms/heroku) instead. </Warning> ```bash Bash theme={null} heroku drains:add "https://appsignal-endpoint.net/logplex?api_key=<push_api_key>&name=<app_name>&environment=<app_environment>" ``` Make sure to replace the placeholders (`<push_api_key>`, `<app_name>` and `<app_environment>`) with your AppSignal organization's Push API key, your app's name and environment. Make sure your app's name and environment match exactly with your app's AppSignal configuration. These values are case sensitive. You can find your Push API key, app name and environment on AppSignal.com at ["App settings > Push & Deploy"](https://appsignal.com/redirect-to/app?to=info). Once the log drain is set up, [Heroku platform errors](/heroku/logplex-errors) and [dashboards](/heroku/dashboards) should appear automatically. Additional setup is required for [Host Metrics](/heroku/host-metrics). ## Fir applications You can configure AppSignal's metrics, error reporting, and dashboards for [Heroku Fir](https://devcenter.heroku.com/articles/generations#fir) applications with a [Telemetry drain](https://devcenter.heroku.com/articles/heroku-telemetry). ```bash Bash theme={null} heroku telemetry:add --app <heroku_app_name> <collector-endpoint-url> --headers '{"AppSignal-Config-Name":"<app_name>","AppSignal-Config-Environment":"<app_environment>","AppSignal-Config-PushApiKey":"<push_api_key>","AppSignal-Config-LanguageIntegration":"heroku-fir","AppSignal-Config-Revision":"unknown","OpenTelemetry-HostName":"heroku"}' ``` Make sure to replace the following placeholders: * `<heroku_app_name>` with the application name in Heroku * `<collector-endpoint-url>` with the URL of your [Hosted Collector](/collector/hosted-vs-self-hosted), which you can find in your organization's [Hosted Collectors settings](https://appsignal.com/redirect-to/organization?to=admin/hosted_collectors) * `<app_name>` with your application's name * `<app_environment>` with your application's environment * and `<push_api_key>` with your AppSignal organization's Push API key. After this, Heroku will create a telemetry drain and send all telemetry signals (traces, metrics, and logs) to AppSignal. This will populate host metrics for the Heroku platform, metrics from first-party services ([Heroku Postgres](https://devcenter.heroku.com/articles/heroku-postgresql) and [Heroku Redis](https://devcenter.heroku.com/categories/heroku-redis)) that your application uses, and will store any logs from the Heroku Platform API. # AppSignal for Java Source: https://docs.appsignal.com/java AppSignal supports Java through OpenTelemetry. This will allow you to send trace, metric, and log data from your Java application to AppSignal via OpenTelemetry. ## We want your feedback! Our OpenTelemetry support is relatively new and we haven't tested it yet with all the different setups out there. Some features may not work with OpenTelemetry data yet. If you encounter any issues or have suggestions for improvement, please contact support or join our Discord server. <CardGroup> <Card title="Contact support" icon="envelope" href="mailto:support@appsignal.com?subject=OpenTelemetry" /> <Card title="Join our Discord" icon="discord" href="https://discord.gg/VreYMePw9e" /> </CardGroup> ## Setting up OpenTelemetry Follow the installation instructions in the next step to set up OpenTelemetry in your application and report data to AppSignal. # AppSignal Java Configuration Source: https://docs.appsignal.com/java/configuration In this documentation, we'll explain how to configure OpenTelemetry in your application, the available options, and the minimal configuration required. The configuration options for the OpenTelemetry resource, set by the `OTEL_RESOURCE_ATTRIBUTES` environment variable, can be found on the [configuration options page](/java/configuration/options). To configure the AppSignal collector, the program used to send data to AppSignal, please refer to the [collector's configuration documentation](/collector/configuration). # Java configuration options Source: https://docs.appsignal.com/java/configuration/options AppSignal for Java can be configured through OpenTelemetry resource attributes. Resource attributes are attributes that apply that every trace reported from the application using OpenTelemetry. These resource attributes should be configured in your application using environment variables, where you also configure the OpenTelemetry exporter to export to the [AppSignal collector](/java/installation). To configure the resource attributes, set an `OTEL_RESOURCE_ATTRIBUTES` environment variable, as shown below: ```bash Shell theme={null} export OTEL_RESOURCE_ATTRIBUTES="\ attribute_key=attribute_value,\ ...,\ last_attribute_key=last_attribute_value" ``` ## Available options * Required options * [`environment`](#option-environment) * [`host.name`](#option-host.name) * [`language_integration`](#option-language_integration) * [`name`](#option-name) * [`push_api_key`](#option-push_api_key) * [`revision`](#option-revision) * [`service.name`](#option-service.name) * Options * [`app_path`](#option-app_path) * [`filter_attributes`](#option-filter_attributes) * [`filter_function_parameters`](#option-filter_function_parameters) * [`filter_request_payload`](#option-filter_request_payload) * [`filter_request_query_parameters`](#option-filter_request_query_parameters) * [`filter_request_session_data`](#option-filter_request_session_data) * [`ignore_actions`](#option-ignore_actions) * [`ignore_errors`](#option-ignore_errors) * [`ignore_logs`](#option-ignore_logs) * [`ignore_namespaces`](#option-ignore_namespaces) * [`request_headers`](#option-request_headers) * [`response_headers`](#option-response_headers) * [`send_function_parameters`](#option-send_function_parameters) * [`send_request_payload`](#option-send_request_payload) * [`send_request_query_parameters`](#option-send_request_query_parameters) * [`send_request_session_data`](#option-send_request_session_data) ## environment <a /> | Field | Value | | ---------------------- | ------------------------------ | | Resource attribute key | `appsignal.config.environment` | | Required | yes | | Type | `String` | | Default value | nil (This is unset by default) | ### Description The environment of the app to be reported to AppSignal. ```bash Shell theme={null} export OTEL_RESOURCE_ATTRIBUTES="\ appsignal.config.environment=production,\ ..." ``` <Note> **Note**: Changing the [name](#option-name) or environment of an existing app will create a new app on AppSignal.com. </Note> ## host.name <a /> | Field | Value | | ---------------------- | -------------------- | | Resource attribute key | `host.name` | | Required | yes | | Type | `String` | | Default value | detected from system | ### Description The `host.name` resource attribute helps AppSignal recognize different hosts for traces and tag the traces automatically with the hostname. ```bash Shell theme={null} HOST_NAME=$(hostname || echo unknown) export OTEL_RESOURCE_ATTRIBUTES="\ host.name=$HOST_NAME,\ ..." ``` ## language\_integration <a /> | Field | Value | | ---------------------- | --------------------------------------- | | Resource attribute key | `appsignal.config.language_integration` | | Required | yes | | Type | `String` | | Default value | nil (This is unset by default) | ### Description AppSignal uses the `language_integration` resource attribute to detect the language of a trace and correctly parse exception backtraces. To set this option, specify the language name in lowercase format: `java`. ```bash Shell theme={null} export OTEL_RESOURCE_ATTRIBUTES="\ appsignal.config.language_integration=java,\ ..." ``` ## name <a /> | Field | Value | | ---------------------- | ------------------------------ | | Resource attribute key | `appsignal.config.name` | | Required | yes | | Type | `String` | | Default value | nil (This is unset by default) | ### Description Name of your application as it should be displayed on AppSignal.com. ```bash Shell theme={null} export OTEL_RESOURCE_ATTRIBUTES="\ appsignal.config.name=My awesome app,\ ..." ``` <Note> **Note**: Changing the name or [environment](#option-env) of an existing app will create a new app on AppSignal.com. </Note> ## push\_api\_key <a /> | Field | Value | | ---------------------- | ------------------------------- | | Resource attribute key | `appsignal.config.push_api_key` | | Required | yes | | Type | `String` | | Default value | nil (This is unset by default) | ### Description The organization-level authentication key to authenticate with our Push API. Read more about the [AppSignal Push API key](/appsignal/terminology#push-api-key). ```bash Shell theme={null} export OTEL_RESOURCE_ATTRIBUTES="\ appsignal.config.push_api_key=00000000-0000-0000-0000-000000000000,\ ..." ``` ## revision <a /> | Field | Value | | ---------------------- | ------------------------------ | | Resource attribute key | `appsignal.config.revision` | | Required | yes | | Type | `String` | | Default value | nil (This is unset by default) | ### Description Set the app revision to report the currently running version of your app. AppSignal will create a deploy marker when this value changes, and tag all incoming data with the current revision. Read more about deploy markers in the [deploy markers topic](/application/markers/deploy-markers). ```bash Shell theme={null} REVISION=$(git rev-parse --short HEAD 2>/dev/null || echo unknown) export OTEL_RESOURCE_ATTRIBUTES="\ appsignal.config.revision=$REVISION,\ ..." ``` ## service.name <a /> | Field | Value | | ---------------------- | ------------------------------ | | Resource attribute key | `service.name` | | Required | yes | | Type | `String` | | Default value | nil (This is unset by default) | ### Description The `service.name` resource attribute helps AppSignal recognize different services for traces and groups the traces automatically in a namespace based on the service name. Choose a name that fits your application, like "Web server", "Background worker", "Email service", "Authentication service", etc. ```bash Shell theme={null} export OTEL_RESOURCE_ATTRIBUTES="\ service.name=My service name,\ ..." ``` ## app\_path <a /> | Field | Value | | ---------------------- | ------------------------------ | | Resource attribute key | `appsignal.config.app_path` | | Required | no | | Type | `String` | | Default value | nil (This is unset by default) | ### Description The location of the app on the host's file system. The `app_path` resource attribute helps AppSignal clean up backtraces by stripping away the absolute app path of backtrace lines. This way only paths within the context of the project directory is shown. This makes our [Backtrace links](/application/backtrace-links) feature possible. ```bash Shell theme={null} export OTEL_RESOURCE_ATTRIBUTES="\ appsignal.config.app_path=$PWD,\ ..." ``` ## filter\_attributes <a /> | Field | Value | | ---------------------- | ------------------------------------ | | Resource attribute key | `appsignal.config.filter_attributes` | | Required | no | | Type | `list(String)` | | Default value | `[]` | ### Description The `filter_attributes` resource attribute allows you to filter out specific attributes from being reported to AppSignal. This can be useful to filter out sensitive or non-relevant information from being reported. If an attribute is filtered out this way, it will not show up in the interface at all. The expected format is a comma-separated list of values. The commas must be percent-encoded (replaced with `%2C`) in the environment variable. You can use the `encode` function provided in the snippet below to encode the list of values: ```bash Shell theme={null} function encode() { echo -n "$@" | sed 's/,/%2C/g' } export OTEL_RESOURCE_ATTRIBUTES="\ appsignal.config.filter_attributes=$(encode "my.secret.attribute,some.opentelemetry.attribute"),\ ..." ``` ## filter\_function\_parameters <a /> | Field | Value | | ---------------------- | --------------------------------------------- | | Resource attribute key | `appsignal.config.filter_function_parameters` | | Required | no | | Type | `list(String)` | | Default value | `[]` | ### Description This resource attribute allows you to filter out any function parameters set in the [`appsignal.function.parameters` span attribute](/guides/custom-data/function-parameters). In the example below, values for the keys listed in the `filter_function_parameters` config option are replaced with `[FILTERED]`. The expected format is a comma-separated list of values. The commas must be percent-encoded (replaced with `%2C`) in the environment variable. You can use the `encode` function provided in the snippet below to encode the list of values: ```bash Shell theme={null} function encode() { echo -n "$@" | sed 's/,/%2C/g' } export OTEL_RESOURCE_ATTRIBUTES="\ appsignal.config.filter_function_parameters=$(encode "api_token,secret"),\ ..." ``` ## filter\_request\_payload <a /> | Field | Value | | ---------------------- | ----------------------------------------- | | Resource attribute key | `appsignal.config.filter_request_payload` | | Required | no | | Type | `list(String)` | | Default value | `[]` | ### Description This resource attribute allows you to filter out any request payload data set in the [`appsignal.request.payload` span attribute](/guides/custom-data/request-parameters). In the example below, values for the keys listed in the `filter_request_payload` config option are replaced with `[FILTERED]`. Read more about [request query parameter filtering](/application/parameter-filtering). The expected format is a comma-separated list of values. The commas must be percent-encoded (replaced with `%2C`) in the environment variable. You can use the `encode` function provided in the snippet below to encode the list of values: ```bash Shell theme={null} function encode() { echo -n "$@" | sed 's/,/%2C/g' } export OTEL_RESOURCE_ATTRIBUTES="\ appsignal.config.filter_request_payload=$(encode "password,cvv"),\ ..." ``` ## filter\_request\_query\_parameters <a /> | Field | Value | | ---------------------- | -------------------------------------------------- | | Resource attribute key | `appsignal.config.filter_request_query_parameters` | | Required | no | | Type | `list(String)` | | Default value | `[]` | ### Description This resource attribute allows you to filter out any request query parameters set in the [`appsignal.request.query_parameters` span attribute](/guides/custom-data/request-parameters). In the example below, values for the keys listed in the `filter_request_query_parameters` config option are replaced with `[FILTERED]`. Read more about [request query parameter filtering](/application/parameter-filtering). The expected format is a comma-separated list of values. The commas must be percent-encoded (replaced with `%2C`) in the environment variable. You can use the `encode` function provided in the snippet below to encode the list of values: ```bash Shell theme={null} function encode() { echo -n "$@" | sed 's/,/%2C/g' } export OTEL_RESOURCE_ATTRIBUTES="\ appsignal.config.filter_request_query_parameters=$(encode "password,cvv"),\ ..." ``` ## filter\_request\_session\_data <a /> | Field | Value | | ---------------------- | ---------------------------------------------- | | Resource attribute key | `appsignal.config.filter_request_session_data` | | Required | no | | Type | `list(String)` | | Default value | `[]` | ### Description The `filter_request_session_data` resource attribute allows you to filter out any request session data set in the [`appsignal.request.session_data` span attribute](/guides/custom-data/request-session-data). In the example below, values for the keys listed in the `filter_request_session_data` config option are replaced with `[FILTERED]`. Read more about [request session data filtering](/application/session-data-filtering). The expected format is a comma-separated list of values. The commas must be percent-encoded (replaced with `%2C`) in the environment variable. You can use the `encode` function provided in the snippet below to encode the list of values: ```bash Shell theme={null} function encode() { echo -n "$@" | sed 's/,/%2C/g' } export OTEL_RESOURCE_ATTRIBUTES="\ appsignal.config.filter_session_data=$(encode "password,cvv"),\ ..." ``` ## ignore\_actions <a /> | Field | Value | | ---------------------- | --------------------------------- | | Resource attribute key | `appsignal.config.ignore_actions` | | Required | no | | Type | `list(String)` | | Default value | `[]` | ### Description With this config option you can specify a list of actions that will be ignored by AppSignal. Everything that happens including exceptions will not be transmitted to AppSignal. This can be useful to ignore health check endpoints or other actions that you don't want to monitor. Read more about [ignoring actions](/guides/filter-data/ignore-actions). The expected format is a comma-separated list of values. The commas must be percent-encoded (replaced with `%2C`) in the environment variable. You can use the `encode` function provided in the snippet below to encode the list of values: ```bash Shell theme={null} function encode() { echo -n "$@" | sed 's/,/%2C/g' } export OTEL_RESOURCE_ATTRIBUTES="\ appsignal.config.ignore_actions=$(encode "GET /health_check,POST /ping"),\ ..." ``` ## ignore\_errors <a /> | Field | Value | | ---------------------- | -------------------------------- | | Resource attribute key | `appsignal.config.ignore_errors` | | Required | no | | Type | `list(String)` | | Default value | `[]` | ### Description This config option allows you to ignore specific errors from being reported to AppSignal. This can be useful to ignore expected errors or errors that can't be solved. Read more about [ignoring errors](/guides/filter-data/ignore-errors). The expected format is a comma-separated list of values. The commas must be percent-encoded (replaced with `%2C`) in the environment variable. You can use the `encode` function provided in the snippet below to encode the list of values: ```bash Shell theme={null} function encode() { echo -n "$@" | sed 's/,/%2C/g' } export OTEL_RESOURCE_ATTRIBUTES="\ appsignal.config.ignore_errors=$(encode "MyCustomError,ExpectedError"),\ ..." ``` ## ignore\_logs <a /> | Field | Value | | ---------------------- | ------------------------------ | | Resource attribute key | `appsignal.config.ignore_logs` | | Required | no | | Type | `list(String)` | | Default value | `[]` | ### Description List of log messages that will be ignored. Any log message containing any of the elements of the list will not be transmitted to AppSignal. A small subset of regex syntax is supported, read more about it in our [Ignore Logs](/guides/filter-data/ignore-logs) guide. The expected format is a comma-separated list of values. The commas must be percent-encoded (replaced with `%2C`) in the environment variable. You can use the `encode` function provided in the snippet below to encode the list of values: ```bash Shell theme={null} function encode() { echo -n "$@" | sed 's/,/%2C/g' } export OTEL_RESOURCE_ATTRIBUTES="\ appsignal.config.ignore_logs=$(encode "^done$,Task .* completed successfully"),\ ..." ``` ## ignore\_namespaces <a /> | Field | Value | | ---------------------- | ------------------------------------ | | Resource attribute key | `appsignal.config.ignore_namespaces` | | Required | no | | Type | `list(String)` | | Default value | `[]` | ### Description This config option allows you to ignore specific namespaces from being reported to AppSignal. This can be useful to ignore specific parts of your application from being monitored. Read more about [namespaces](/application/namespaces). The expected format is a comma-separated list of values. The commas must be percent-encoded (replaced with `%2C`) in the environment variable. You can use the `encode` function provided in the snippet below to encode the list of values: ```bash Shell theme={null} function encode() { echo -n "$@" | sed 's/,/%2C/g' } export OTEL_RESOURCE_ATTRIBUTES="\ appsignal.config.ignore_namespaces=$(encode "admin,secret"),\ ..." ``` ## request\_headers <a /> | Field | Value | | ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | | Resource attribute key | `appsignal.config.request_headers` | | Required | no | | Type | `list(String)` | | Default value | `["accept", "accept-charset", "accept-encoding", "accept-language", "cache-control", "connection", "content-length", "host", "range"]` | ### Description Configure which request headers to include when a request is made to an HTTP server. This option is an allowlist. It only includes the headers that are configured. If the list is empty, no headers are included. The request headers are read from the `http.request.header.<key>` [OpenTelemetry span attributes](https://opentelemetry.io/docs/specs/semconv/http/http-spans/), where `<key>` is the normalized header name (lowercase). To not set any headers, explicitly set the resource attribute value to an empty value. The expected format is a comma-separated list of values. The commas must be percent-encoded (replaced with `%2C`) in the environment variable. You can use the `encode` function provided in the snippet below to encode the list of values: ```bash Shell theme={null} function encode() { echo -n "$@" | sed 's/,/%2C/g' } # Only send these specific headers export OTEL_RESOURCE_ATTRIBUTES="\ appsignal.config.request_headers=$(encode "accept,request_method,content_length"),\ ..." # Do not send any headers export OTEL_RESOURCE_ATTRIBUTES="\ appsignal.config.request_headers=,\ ..." ``` ## response\_headers <a /> | Field | Value | | ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | | Resource attribute key | `appsignal.config.response_headers` | | Required | no | | Type | `list(String)` | | Default value | `["accept", "accept-charset", "accept-encoding", "accept-language", "cache-control", "connection", "content-length", "host", "range"]` | ### Description Configure which response headers to include when a request is made by an HTTP client. This option is an allowlist. It only includes the headers that are configured. If the list is empty, no headers are included. The response headers are read from the `http.response.header.<key>` [OpenTelemetry span attributes](https://opentelemetry.io/docs/specs/semconv/http/http-spans/), where `<key>` is the normalized header name (lowercase). To not set any headers, explicitly set the resource attribute value to an empty array. The expected format is a comma-separated list of values. The commas must be percent-encoded (replaced with `%2C`) in the environment variable. You can use the `encode` function provided in the snippet below to encode the list of values: ```bash Shell theme={null} function encode() { echo -n "$@" | sed 's/,/%2C/g' } # Only send these specific headers export OTEL_RESOURCE_ATTRIBUTES="\ appsignal.config.response_headers=$(encode "accept,request_method,content_length"),\ ..." # Do not send any headers export OTEL_RESOURCE_ATTRIBUTES="\ appsignal.config.response_headers=,\ ..." ``` ## send\_function\_parameters <a /> | Field | Value | | ---------------------- | ------------------------------------------- | | Resource attribute key | `appsignal.config.send_function_parameters` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `true` | ### Description Configure whether to include function parameters in traces. If set to `false` no such data is sent to our servers. These values are set with the [`appsignal.function.parameters` span attribute](/guides/custom-data/function-parameters). ```bash Shell theme={null} export OTEL_RESOURCE_ATTRIBUTES="\ appsignal.config.send_function_parameters=false,\ ..." ``` ## send\_request\_payload <a /> | Field | Value | | ---------------------- | --------------------------------------- | | Resource attribute key | `appsignal.config.send_request_payload` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `true` | ### Description Configure whether to send request payload data in traces. If set to `false` no such data is sent to our servers. These values are set with the [`appsignal.request.payload` span attribute](/guides/custom-data/request-parameters). For more information please read about [request payload filtering](/application/parameter-filtering). ```bash Shell theme={null} export OTEL_RESOURCE_ATTRIBUTES="\ appsignal.config.send_request_payload=false,\ ..." ``` ## send\_request\_query\_parameters <a /> | Field | Value | | ---------------------- | ------------------------------------------------ | | Resource attribute key | `appsignal.config.send_request_query_parameters` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `true` | ### Description Configure whether to include request query parameters in traces. If set to `false` no such data is sent to our servers. These values are set with the [`appsignal.request.query_parameters` span attribute](/guides/custom-data/request-parameters). For more information please read about [request parameter filtering](/application/parameter-filtering). ```bash Shell theme={null} export OTEL_RESOURCE_ATTRIBUTES="\ appsignal.config.send_request_query_parameters=false,\ ..." ``` ## send\_request\_session\_data <a /> | Field | Value | | ---------------------- | -------------------------------------------- | | Resource attribute key | `appsignal.config.send_request_session_data` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `true` | ### Description Configure whether to send request session data in traces. If set to `false` no such data is sent to our servers. These values are set with the [`appsignal.request.session_data` span attribute](/guides/custom-data/request-session-data). For more information please read about [request session data filtering](/application/session-data-filtering). ```bash Shell theme={null} export OTEL_RESOURCE_ATTRIBUTES="\ appsignal.config.send_request_session_data=false,\ ..." ``` # Java Custom Instrumentation Source: https://docs.appsignal.com/java/custom-instrumentation AppSignal is compatible with OpenTelemetry instrumentation packages. Some of these instrumentation packages may require additional setup. These instrumentations do not not always include all the information you need to debug issues. For more fine-grained reporting, you can add custom instrumentation. We support [OpenTelemetry tracing][manual] as laid out in the OpenTelemetry documentation. It's possible to add more data to span using OpenTelemetry span attributes. There are also AppSignal span attributes that can change how traces are grouped and some attributes that allow for filtering out sensitive data. ## Creating a new span Using the tracer from the global tracer provider, create a new span. <CodeGroup> ```java Java theme={null} import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.Tracer; import io.opentelemetry.context.Scope; public void someFunction() { // Get OpenTelemetry tracer Tracer tracer = GlobalOpenTelemetry.getTracer("my-app"); // Create a new span Span span = tracer.spanBuilder("My span").startSpan(); // Set attributes span.setAttribute("operation.name", "handle_request"); // Your application logic here // Close the span span.end(); } ``` </CodeGroup> *Note: In these examples we're using the global tracer provider set by OpenTelemetry. You may want to inject the tracer into your classes for better testability.* ## Get the current span You can also fetch the current active span: <CodeGroup> ```java Java theme={null} import io.opentelemetry.api.trace.Span; public void someFunction() { Span span = Span.current(); // Set attributes on the current span span.setAttribute("user.id", userId); span.setAttribute("operation.name", "database_query"); } ``` </CodeGroup> *Note: This will only return a span if one is already active.* More ways to create and get spans are documented on the [OpenTelemetry Java Instrumentation page][manual]. ## AppSignal attributes Once you have created, or fetched, a span, you can set certain attributes that are specific to AppSignal to customize how the data arrives in AppSignal. <CodeGroup> ```java Java theme={null} Span span = // Create a new span or fetch the current span span.setAttribute("attribute_name", "attribute_value"); ``` </CodeGroup> See our guides for more information on what custom AppSignal attributes are supported: * [Tagging guide](/guides/tagging) * [Data customization guide](/guides/custom-data) [manual]: https://opentelemetry.io/docs/languages/java/api/ # OpenTelemetry Java Installation Source: https://docs.appsignal.com/java/installation Please follow the [installation guide](/guides/new-application) first, when adding a new application to AppSignal. Then make sure to [install the AppSignal collector](/collector/installation) before proceeding. To install and configure OpenTelemetry for your Java application, we recommend using the OpenTelemetry Java agent to export data to the AppSignal collector. This agent will automatically instrument your application. ## Download the OpenTelemetry Java agent Download the OpenTelemetry Java agent from the [latest release on Github](https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/latest/download/opentelemetry-javaagent.jar). When running your application, the OpenTelemetry Java agent will need to be present. ## Run your application with the agent When running your application, you will need to configure the Java runtime to load the OpenTelemetry Java agent. Change how you start your application to load the OpenTelemetry Java agent with your application: <CodeGroup> ```shell Shell theme={null} java -javaagent:/path/to/opentelemetry-javaagent.jar -jar your-application.jar ``` </CodeGroup> Replace `/path/to/opentelemetry-javaagent.jar` with the path to the downloaded agent and `your-application.jar` with the path to your application's JAR file. ### Gradle When using Gradle, you can add the agent to the task that starts your application in the `build.gradle` file: <CodeGroup> ```groovy title="build.gradle.kts" theme={null} tasks.bootRun { jvmArgs = listOf("-javaagent:/path/to/opentelemetry-javaagent.jar") // With any other configuration after } ``` </CodeGroup> ## Configure the agent The agent may be configured using Java properties or environment variables. We recommend using environment variables for configuration. First, configure the agent to export traces and logs to the AppSignal collector: <CodeGroup> ```shell Shell theme={null} # Export traces and metrics to the AppSignal collector using the OTLP protocol. # Replace `http://localhost:8099` with the address of your AppSignal collector # if it's running on another host. export OTEL_TRACES_EXPORTER=otlp export OTEL_METRICS_EXPORTER=otlp export OTEL_LOGS_EXPORTER=otlp export OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:8099 ``` </CodeGroup> Then, configure the OpenTelemetry resource attributes required by AppSignal: <CodeGroup> ```shell Shell theme={null} # Replace these values with your AppSignal application name, environment # and push API key. These are used by the resource attributes configuration below. APPSIGNAL_APP_NAME=your-app-name APPSIGNAL_APP_ENV=production APPSIGNAL_PUSH_API_KEY=your-push-api-key # Optionally, set a custom revision and hostname. If not set, the resource attributes # configuration below will use the current Git revision and system hostname. # REVISION=your-custom-revision # HOSTNAME=your-custom-hostname # Set the name of the service that is being monitored. A common choice is the # name of the framework used. This is used to group traces and metrics in AppSignal. export OTEL_SERVICE_NAME=my-service-name export OTEL_RESOURCE_ATTRIBUTES="\ appsignal.config.name=$APPSIGNAL_APP_NAME,\ appsignal.config.environment=$APPSIGNAL_APP_ENV,\ appsignal.config.push_api_key=$APPSIGNAL_PUSH_API_KEY,\ appsignal.config.revision=${REVISION:-$(git rev-parse --short HEAD 2>/dev/null || echo unknown)},\ appsignal.config.language_integration=java,\ appsignal.config.app_path=$PWD,\ host.name=${HOSTNAME:-$(hostname)}\ " ``` </CodeGroup> ## Test the app! Now that all the components are connected, start your app with the required environment variables and test if you see data arrive in AppSignal. Check the ["Errors > Issue list"](https://appsignal.com/redirect-to/app?to=exceptions) and ["Performance > Traces"](https://appsignal.com/redirect-to/app?to=performance/traces) page specifically. If after following our installation instructions you still don't see data in AppSignal, [let us know](mailto:support@appsignal.com?subject=OpenTelemetry%20beta%20issue) and we'll help you finalize your OpenTelemetry installation! # Java Instrumentations Source: https://docs.appsignal.com/java/instrumentations The OpenTelemetry Java agent instrumentation includes [many instrumentations by default](https://github.com/open-telemetry/opentelemetry-java-instrumentation/tree/main/instrumentation/), including Spring, Log4J, and Kafka. If you're missing any trace, metric, or log data, you may need to add additional instrumentation packages to monitor specific libraries your application uses that are not instrumented by default. This page lists some of the OpenTelemetry for Java instrumentations that AppSignal supports. If a library is not listed here, it doesn't mean it's not supported. It is either included by default, or we haven't indexed it yet. The complete list of available instrumentation packages for Java can be found on the [OpenTelemetry registry for Java](https://opentelemetry.io/ecosystem/registry/?language=java\&component=instrumentation). <Note> Is your app not reporting the data you'd like to see? Don't hesitate to [contact us](mailto:support@appsignal.com) and let us know which libraries you're using. We'll try to help get more useful data reported. </Note> ## Additional Java library instrumentations * [Elasticsearch](/java/instrumentations/elasticsearch) # Elasticsearch Instrumentation Source: https://docs.appsignal.com/java/instrumentations/elasticsearch The [Elasticsearch Java client](https://www.elastic.co/docs/reference/elasticsearch/clients/java/getting-started) provides built-in OpenTelemetry instrumentation that automatically traces operations performed against Elasticsearch clusters. No additional instrumentation package is required. The built-in instrumentation captures spans for search queries, index operations, and other interactions with your Elasticsearch cluster. For a list of features and installation guide, consult the [Elasticsearch Java client documentation][es docs]. Having trouble reporting Elasticsearch data to AppSignal, please [contact AppSignal support](mailto:support@appsignal.com). [es docs]: https://www.elastic.co/docs/reference/elasticsearch/clients/java # Kubernetes metrics Source: https://docs.appsignal.com/kubernetes/metrics [AppSignal for Kubernetes](https://github.com/appsignal/appsignal-kubernetes) extracts metrics from Kubernetes clusters. After adding the AppSignal for Kubernetes deployment to your cluster, a Cluster Metrics section appears for your AppSignal application, displaying metrics for each node and each pod, as well as an overview of your cluster. ## Installation To start reporting Kubernetes cluster metrics to AppSignal: 1. [Store your AppSignal API key in a secret](#store-your-appsignal-api-key-in-a-secret) 2. [Deploy to your cluster](#deploy-to-your-cluster) ### Store your AppSignal API key in a secret Create a secret in your Kubernetes cluster containing your AppSignal app-specific push API key: <CodeGroup> ```bash Bash theme={null} kubectl create secret generic appsignal -n appsignal --from-literal=api-key=<APPSIGNAL_API_KEY> ``` </CodeGroup> You can find your *app-specific* push API key in [your application's settings](https://appsignal.com/redirect-to/app?to=info). ### Deploy to your cluster Once you've created the AppSignal API key secret, add the AppSignal for Kubernetes deployment to your cluster: <CodeGroup> ```bash Bash theme={null} kubectl apply -f https://raw.githubusercontent.com/appsignal/appsignal-kubernetes/main/deployment.yaml ``` </CodeGroup> This will create the `appsignal` namespace and deploy AppSignal for Kubernetes in that namespace. Alternatively, install AppSignal for Kubernetes through its Helm chart: ```bash Bash theme={null} helm repo add appsignal-kubernetes https://appsignal.github.io/appsignal-kubernetes helm install appsignal-kubernetes appsignal-kubernetes/appsignal-kubernetes --create-namespace --namespace appsignal ``` Once configured, AppSignal for Kubernetes will start reporting metrics automatically. ## Cluster Metrics In AppSignal, the Host Metrics page will now be replaced with a Cluster Metrics page to show information about pods and nodes in your cluster. You will be able to see graphs representing useful metrics over time, such as: * **CPU Usage:** CPU usage stats per node or pod * **Memory Usage:** memory usage statistics, comparing the used memory to what's available per node or pod * **Swap Usage:** swap usage statistics, comparing the used swap to what's available per node or pod * **Disk Usage:** disk usage statistics, comparing the used disk space to what's available per node * **Network usage:** network usage, split by received and transmitted bytes, per node ## Support If you are experiencing any difficulties configuring your application's Kubernetes metrics, [contact support](mailto:support@appsignal.com), and we'll help you get your metrics flowing. # AppSignal Labs Source: https://docs.appsignal.com/labs Try experimental features early and help shape what we build next. Labs is where new ideas land first, before they make it into the rest of AppSignal. ## What to expect Three things to keep in mind before you opt in. <CardGroup> <Card title="Early access" icon="bolt"> Use features before they're generally available. </Card> <Card title="Rough edges" icon="wrench"> Features may be incomplete or change without notice. Not covered by our SLA. </Card> <Card title="Direct influence" icon="message"> Your feedback goes straight to the team building the feature. </Card> </CardGroup> ## Stages Each Labs feature sits at one of three stages, which tells you how to get involved: * **In research:** We're exploring the problem and shaping the solution. You may see early pull requests, prototypes, or open calls for UX research sessions. Join a session to help us scope what we build. * **In preview:** Self-serve and ready to try. Turn it on yourself, explore what's there, and share your feedback in our [Discord](https://discord.gg/EjF6ykYx63) channel. * **In beta:** Closer to general availability. Some beta features sit behind a feature flag and may need to be enabled by [Support](mailto:support@appsignal.com). We're rolling these out gradually as we polish the rough edges. ## Current Labs features <Card title="Apdex" icon="gauge-high"> **In beta** Measure how satisfied your users are with your application's performance. Set **Satisfied** and **Tolerating** response time thresholds per namespace, and AppSignal generates `apdex` and `apdex_counts` metrics you can add to dashboards and notifications. Display them as a **single value** or **time series**, so you can see your current score at a glance. [Share feedback on Discord β†’](https://discord.gg/EjF6ykYx63) </Card> <Card title="Log-based metrics" icon="chart-line"> **In beta** Turn data from your logs into metrics without writing any new code or leaving the Logs page. Filter your logs to the events you care about, like requests to `/api/orders`, select **Create a metric** from a log line, and AppSignal builds a Count, Gauge, or Measurement metric using the query, severity, and source you already had open. Use it on a dashboard or in a trigger. [Read the doc β†’](/logging/metrics) [Share feedback on Discord β†’](https://discord.gg/EjF6ykYx63) </Card> <Card title="AppSignal CLI" icon="terminal"> **In beta** A command-line interface for AppSignal, built in Rust. Designed for both humans and LLMs to query your AppSignal data from the terminal. Install it with Homebrew to get started. In the future, we'll keep expanding the CLI toward feature parity with the AppSignal API. [Read the docs β†’](/cli) [Install the CLI β†’](https://github.com/appsignal/homebrew-appsignal-cli#install) [See the latest releases β†’](https://github.com/appsignal/homebrew-appsignal-cli/releases) </Card> <Card title="JavaScript web vitals" icon="gauge"> **In research** Frontend monitoring for your browser apps. We're exploring a browser section that surfaces frontend errors along with the context of what happened before them, plus Core Web Vitals from real users, broken down per page. Track the standard browser metrics, LCP, INP, CLS, FCP, and TTFB, to see how each page performs. Filter by app version to compare the performance of each release. Useful for developers debugging slow pages and for analytics. [Join the research β†’](https://discord.gg/EjF6ykYx63) </Card> <Card title="Distributed tracing" icon="diagram-project"> **In research** Follow a request as it travels across your services and applications. We're exploring distributed tracing built on OpenTelemetry, with a trace timeline that shows every span in a request, even when it crosses service boundaries, so you can see where the time goes and where one service hands off to another. A service map surfaces the upstream and downstream callers around a trace, answering who you depend on and who depends on you. Handy for debugging slow requests and understanding how your services fit together. We're now looking for people to try out the early UI and tell us what works and what they'd want from it. If you'd like to help shape where this goes, we'd love to hear from you. [Join the research β†’](https://discord.gg/EjF6ykYx63) </Card> ## Get involved <CardGroup> <Card title="UX research sessions" icon="video" href="https://discord.gg/EjF6ykYx63"> 30-minute video calls where you share what's working and what isn't. </Card> <Card title="Feedback" icon="discord" href="https://discord.gg/EjF6ykYx63"> Use the in-feature feedback button or join us on Discord. </Card> </CardGroup> ## FAQ <AccordionGroup> <Accordion title="Will Labs features affect my production data?"> No. Labs features operate alongside your existing setup with explicit opt-in where needed. </Accordion> <Accordion title="Can I disable a Labs feature?"> Yes, at any time. Your configuration is preserved. </Accordion> <Accordion title="What happens to my feedback?"> The team building that feature reads every piece. </Accordion> </AccordionGroup> # AppSignal Logging Source: https://docs.appsignal.com/logging Having quick access to your application’s logs is crucial for troubleshooting issues and assessing the health of various components, from your database to your messaging queue. AppSignal Logging consolidates your application’s logs, enabling you to store, view, and query them, offering deeper insights into your application's performance and behavior. If you need to store logs for long retention periods, you can export them to an S3-compatible storage solution using the [Long-Term Log Storage add-on](#log-retention). ### AppSignal Logging helps you answer questions like ## Getting started Our documentation covers everything you need to know to get AppSignal Logging up and running with your application. * [How to configure logging](/logging/configuration) * [How to manage your logs](/logging/log-management) * [How to query your logs](/logging/query-syntax) * [How to export your logs with Long-term Log Storage](/logging/long-term-log-storage) * [How to create and manage triggers](/logging/triggers) * [How to troubleshoot issues](/logging/troubleshooting) ## Supported AppSignal Integrations The following AppSignal integrations feature out-of-the-box support for AppSignal Logging: * [Ruby](/logging/integrations/ruby) * [Elixir](/logging/integrations/elixir) * [Node.js](/logging/integrations/nodejs) * [Go](/logging/integrations/go) * [Java](/logging/integrations/java) * [PHP](/logging/integrations/php) * [Python](/logging/integrations/python) ## Best Practices To log or not to log, that can be a tricky question to answer. The best kinds of logs are descriptive, contextual, and concise. With AppSignal, you can get the most out of your logs by utilizing features like [custom attributes](/logging/formatting), which allow you to add additional, filterable data to your log lines. You can read our [Learning Center article on logging best practices](https://www.appsignal.com/learning-center/what-logs-should-i-store) for more information on properly utilizing your application logs. ## Log Retention <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> Retention will vary depending on your plan. You can find actual retention and pricing information on our [plans page](https://www.appsignal.com/plans). If you need to store logs for longer periods, you can export them to an S3-compatible storage solution using the [Long-Term Log Storage add-on](/support/business-add-ons#long-term-log-storage). This add-on allows you to retain your logs beyond the 30-day period AppSignal typically stores them, giving you greater control over your log data retention. For setup instructions, visit the [Long-Term Log Storage setup guide](/logging/long-term-log-storage). ## Limitations AppSignal Logging complements our APM features by capturing important events like slow database queries, admin activity, and outgoing API calls. However, there are some limitations: * We support up to **500k log lines per minute per app**. * Log lines can be up to **10,000 characters**, with any excess being truncated. * Deeply nested JSON payloads are not supported. For advanced monitoring and custom data tracking, we recommend using our [Errors](https://www.appsignal.com/tour/errors) and [Performance](https://www.appsignal.com/tour/performance) features, which are better suited for such use cases. # Configure Logging Source: https://docs.appsignal.com/logging/configuration This documentation will take you through all the necessary steps and additional information needed when adding a new log source to your application. ## Creating a Log Source <Note> ✨ You do not need to create a log source when sending logs directly from an AppSignal integration. A log source will be automatically created for you. Follow the instructions for [logging from AppSignal integrations](/logging/integrations). </Note> To send logs to AppSignal, you'll first need to configure your log sources. Your application could have many log sources, like a database or app process. You will need to do this once per log source. For example, if you want to send MongoDB and NGINX logs to AppSignal, you'd need to create a source for each of these integrations. <img alt="Screenshot of Logging Sources page" /> To do this, navigate to the Logging page in the AppSignal application and click on the `Add log source` button in the top right of the page. A pop-up will appear, prompting you to name your source. It's important to give your source a descriptive name like Redis or MongoDB so that you can successfully query these logs in the future. <img alt="Add new Log Source form" /> ### Choose Your Platform <Tip> Are you setting up logging for Vercel? There are some additional steps required when creating a Vercel log source. Read our [Vercel Configuration documentation](/vercel/logs) for step-to-step setup instructions. </Tip> We support sending logs to AppSignal from various sources and platforms and are hard at work to add support for more. You can find out more about the platforms supported in this documentation's [Platform Configuration](#platform-configuration) section. If your platform is not listed, you can send logs to [one of our endpoints](/logging/endpoints) directly. ### Choose The Message Format <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> Some sources are based on a third-party integration, where you can't control the format of the log line. In this case, you can choose the format of the log line that AppSignal will attempt to parse the `message` from. This allows you to add structure to your log lines, without controlling the surrounding log line format. For example, if you use the Netlify integration, which takes care of sending log lines to AppSignal in their own format, allowing us to extract the correct time and hostname, you can choose the `json` log format to add additional attributes to a log line. When we support parsing the log message, we support these formats: * [Plaintext](/logging/formatting#plaintext) * [Logfmt](/logging/formatting/logfmt) * [JSON](/logging/formatting/json) Read more about how to format your messages in the [Formatting Documentation](/logging/formatting). ### Create Source Once you've chosen the name and format of your new source is created, it will be listed in the Log Sources table on the Logs page, alongside a generated API key. <img alt="Screenshot of Log Sources table highlighting API key" /> You will now need to configure your application to send logs to AppSignal using one of the [platforms we support](#platform-configuration). ## Platform Configuration Once you've created a new source, you'll need to configure your application to send logs to AppSignal. This should be via the same platform you defined when creating your log source. ### Supported Logging Platforms * AWS CloudWatch logs through Amazon Data Firehose * [Manual setup](/logging/platforms/cloudwatch) * [CloudFormation setup](/logging/platforms/cloudwatch-cloudformation) * [Clever Cloud](/logging/platforms/clevercloud) * [Gigalixir Log Drain](/logging/platforms/gigalixir) * [Heroku](/logging/platforms/heroku) * [Netlify](/logging/platforms/netlify) * [Render](/logging/platforms/render) * [Scalingo](/logging/platforms/scalingo) * [Vector](/logging/platforms/vector) * [Vercel](/vercel/logs) ### Supported Logging Endpoints * [HTTP](/logging/endpoints/http) * [HTTP-JSON](/logging/endpoints/http-json) * [HTTP-Syslog](/logging/endpoints/http-syslog) * [Syslog](/logging/endpoints/syslog) ## Completing Setup <Note> As AppSignal only stores logs that are sent to it from your application, you will only be able to see logs created **after** you've completed your configuration. </Note> Once you've configured your chosen platform, you'll be able to view and query your logs from the `All logs` page in the AppSignal application. There's more information on how to manage, view, and query your logs in this guide's [next step](/logging/log-management). <img alt="Screenshot of expanded log" /> ## Adding Long-Term Storage You can configure a source for storing logs with your own secure S3-compatible storage using AppSignal's Long-term Log Storage. This feature requires a paid Business Add-On. AppSignal will continue to retain your logs for 30 days. Learn more in our [Long-Term Log Storage documentation](/logging/long-term-log-storage). ## Troubleshooting and support If you've followed the above steps and cannot see any logs in AppSignal, you may want to read our [Troubleshooting Guide](/logging/troubleshooting) or [reach out to us for assistance](mailto:support@appsignal.com). # Supported Log Endpoints Source: https://docs.appsignal.com/logging/endpoints ## Supported Log Endpoints When you can't use any of our [platforms](#supported-platforms) or [integrations](#supported-appsignal-integrations), you can send logs directly to one of our four endpoints available: * **[HTTP-JSON](/logging/endpoints/http-json)**: this endpoint expects NDJSON formatted log lines in the format described here. * **[HTTP-Syslog](/logging/endpoints/http-syslog)**: this endpoint expects Syslog-formatted log lines in the format described here. * **[HTTP](/logging/endpoints/http)**: this endpoint accepts plain-text log lines, that don't have any additional information. We use the time we received the log line as the timestamp, and other fields such as group and hostname are empty. In order to add additional information to a log line, you can format the log lines with one of the message formats described below. * **[Syslog](/logging/endpoints/syslog)**: this endpoint expects Syslog-formatted log lines in the format described here. You can use a specific format in the log message to override log information, or add additional attributes for a log line. ### Supported Platforms AppSignal Log Management supports the following platforms: * AWS CloudWatch logs through Amazon Data Firehose * [Manual setup](/logging/platforms/cloudwatch) * [CloudFormation setup](/logging/platforms/cloudwatch-cloudformation) * [Clever Cloud](/logging/platforms/clevercloud) * [Gigalixir Log Drain](/logging/platforms/gigalixir) * [Heroku](/logging/platforms/heroku) * [Netlify](/logging/platforms/netlify) * [Render](/logging/platforms/render) * [Scalingo](/logging/platforms/scalingo) * [Vector](/logging/platforms/vector) * [Vercel](/vercel/logs) ### Supported AppSignal Integrations The following AppSignal Integrations support AppSignal Logging: * [Ruby](/logging/integrations/ruby) * [Elixir](/logging/integrations/elixir) * [Node.js](/logging/integrations/nodejs) * [Go](/logging/integrations/go) * [Java](/logging/integrations/java) * [PHP](/logging/integrations/php) * [Python](/logging/integrations/python) # HTTP Configuration Source: https://docs.appsignal.com/logging/endpoints/http <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> The HTTP endpoint is the most flexible endpoint to send logs to AppSignal. You can format the message in multiple ways as described below. If you are using a language that has an integration library for AppSignal, we recommend using one of the [integration libraries](/logging/integrations) instead of the HTTP endpoint. If you are creating a custom integration, we recommend using the [HTTP-JSON](/logging/endpoints/http-json) endpoint to guarantee the messages are formatted exactly as intended. ## Endpoint You can `POST` logs to AppSignal. Your logs must be formatted in `JSON`, `Logfmt` or `Plaintext` and sent to the following endpoint: ```sh Shell theme={null} https://appsignal-endpoint.net/logs?api_key=YOUR_LOG_SOURCE_API_KEY ``` *Replace `YOUR_LOG_SOURCE_API_KEY` with the key provided when [creating a log source](/logging/configuration#creating-a-log-source).* We will use the time our servers receive the `POST` request as the log timestamp. The default severity will be `INFO`. You can send the `hostname`, `severity` and `group/appname` parameters by appending them to the URL, for example: ```sh Shell theme={null} https://appsignal-endpoint.net/logs?group=app&hostname=frontend1&severity=debug&api_key=YOUR_LOG_SOURCE_API_KEY ``` You can send multiple log lines by separating each log line with a-formatted message overrides the hostname newline character: `\n` ## Structured messages In order to add additional metadata to a log line, you can send a structured message. ### Plaintext By default the source is created with the `Plaintext` formatter selected, you can send any string as the message part of the log line, for example: <CodeGroup> ```shell Shell theme={null} This is a log message And this is another message ``` </CodeGroup> Will result in two log lines with the message `This is a log message` and `And this is another message` respectively. ### Logfmt When `Logfmt` is selected as the message format, you can send a log line with key-value pairs separated by a space, for example: <CodeGroup> ```shell Shell theme={null} This is a log message user_id=123 action=login This is another log message user_id=123 action=logout ``` </CodeGroup> Will result in two log lines with the message `This is a log message` and `This is another log message` respectively, and the following attributes: <CodeGroup> ```json JSON theme={null} { "user_id": 123, "action": "login" } ``` </CodeGroup> <CodeGroup> ```json JSON theme={null} { "user_id": 123, "action": "logout" } ``` </CodeGroup> ### JSON When `JSON` is selected as the message format, you can send a log line with a JSON object, for example: <CodeGroup> ```shell Shell theme={null} {"message": "This is a log message", "user_id": 123, "action": "login"} {"msg": "This is another log message", "user_id": 123, "action": "logout"} ``` </CodeGroup> We expect either a `msg` or `message` key for the log line message, and any other keys will be added as attributes. If no `msg` or `message` key is provided, we'll use the entire (unparsed) JSON object as the message. Attributes will still be parsed and added to this line. You can read more about the specifics of message formatting in our [formatting](/logging/formatting) documentation. # HTTP-JSON Configuration Source: https://docs.appsignal.com/logging/endpoints/http-json <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> ## Endpoint You can `POST` logs to AppSignal. Your logs must be formatted in [`NDJSON`](#ndjson) and sent to the following endpoint: <CodeGroup> ```shell Shell theme={null} https://appsignal-endpoint.net/logs/json?api_key=YOUR_LOG_SOURCE_API_KEY ``` </CodeGroup> ## NDJSON Our HTTP-JSON endpoint expects the logs to be sent in an `NDJSON` format to our endpoint. `NDJSON` stands for Newline Delimited JSON, which means that each log line is its own JSON object, for example: <CodeGroup> ```shell Shell theme={null} {"timestamp": "2022-06-02T04:17:25.783Z", "message": "foo", [...]} {"timestamp": "2022-06-02T04:17:26.000Z", "message": "bar", [...]} ``` </CodeGroup> ### Required Data Below is an example of a (prettified) `NDJSON` message. You can read more about the data AppSignal requires in the [Required Fields](#required-fields) section. #### Example message <Warning> **Warning:** This is formatted using newlines for readability. Your client **must** send the log line as a single line, without newlines. </Warning> <CodeGroup> ```json JSON theme={null} { "timestamp": "2022-06-02T04:17:25.783Z", "group": "organisations", "severity": "warn", "message": "This is a test message", "hostname": "frontend1", "attributes": { "org": "appsignal", "step": 1, "seen_terms": true, "entries": 10.01 } } ``` </CodeGroup> #### Required Fields <Warning> AppSignal will silently drop any message that does not contain the required fields below or any incorrect values. </Warning> The `NDJSON` payload you send to AppSignal must contain the following fields: #### timestamp A `RFC 3339` formatted timestamp with a 3-digit nanosecond precision. ```yaml YAML theme={null} YYYY-MM-DDThh:mm:ss.sss 2022-01-12T07:20:50.520Z ``` #### group One-word string that allows the user to separate log lines by a certain context (e.g., logs for a specific part of your application, group could be "admin", "payments", "database", or "background"). #### severity The severity field accepts the following values: `unknown`, `trace`, `debug`, `info`, `notice`, `warn`, `error`, `critical`, `alert` and `fatal`. #### message `Plaintext` message. #### hostname Hostname of the server sending the message. #### Optional fields The following fields are optional but recommended for richer log data: #### attributes Attributes that can be used to filter or search the message, with the following rules: * Attributes cannot be nested or contain arrays * The maximum key size is `50` characters * The maximum amount of attributes is `100` * The following primitives are accepted as values: * String: ideally used as "tags," e.g. one-word values, with a maximum of `100` characters * Integer: `10` * Double: `0.01` * Boolean: `true`/`false` #### format Overrides the log source's configured format when parsing the `message`. Accepts `plaintext`, `logfmt`, `json` or `autodetect`; unknown values are ignored. # HTTP Syslog Configuration Source: https://docs.appsignal.com/logging/endpoints/http-syslog <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> ## Endpoint You can `POST` logs to AppSignal. Your logs must be formatted in `Syslog` and sent to the following endpoint: ```bash Shell theme={null} https://appsignal-endpoint.net/logs/syslog?api_key=YOUR_LOG_SOURCE_API_KEY ``` *Replace `YOUR_LOG_SOURCE_API_KEY` with the key provided when [creating a log source](/logging/configuration#creating-a-log-source).* The Syslog lines should be separated by a newline character: `\n`. The log line should be sent in the syslog [RFC 5424](https://www.rsyslog.com/doc/master/configuration/modules/pmrfc5424.html) (Request For Comment) format: ```bash Shell theme={null} <%pri%>%protocol-version% %timestamp:::date-rfc3339% %HOSTNAME% %app-name% %procid% %msgid% %msg%\n" <14>1 2017-07-26T14:47:35.869952+05:30 my_hostname custom_appname 5678 some_unique_msgid - Some other message" ``` ## Structured messages The `message` part of a syslog message can be formatted either in `JSON`, `Logfmt` or `Plaintext`. Formatting the message in `JSON` or `Logfmt` allows you to add additional (structured) data attributes that can be used to find/filter messages on. For more information about the specifics of message formatting, see our [formatting](/logging/formatting) documentation. # Syslog Configuration Source: https://docs.appsignal.com/logging/endpoints/syslog <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> ## Install TLS Package To send logs to AppSignal via syslog, you'll need to have installed rsyslog's [TLS (Transport Layer Security)](/appsignal/terminology#tls) package. You can check to see if the package is already installed on your server using the below command: <CodeGroup> ```shell Shell theme={null} sudo apt list rsyslog-gnutls --installed ``` </CodeGroup> If the package is not installed, you can install it using the below command: <CodeGroup> ```shell Shell theme={null} sudo apt install rsyslog-gnutls ``` </CodeGroup> ## Setup Syslog AppSignal generates a Syslog code snippet for you, available on the source management page. To view this snippet, find the source you wish to configure from the Manage Sources overview and click "Manage source". You will be redirected to a page, that will look similar to the example below: <img alt="Screenshot of Source Management" /> On this page, you will be able to find the "Installation instructions" for your source. These instructions will include a code snippet you copy and use as your configuration file. You should save this file in the `etc/rsyslog.d` directory. Once you've created and saved your configuration, you will need to restart rsyslog so that it begins sending logs to AppSignal, using the restart command from a terminal with root access: <CodeGroup> ```shell Shell theme={null} /etc/rc.d/init.d/systemctl restart rsyslogd ``` </CodeGroup> If you are unsure about this step, you can always [reach out](mailto:support@appsignal.com) for assistance. We'll help you to get those logs flowing! ## Domain and Port Information Our domain and port are as follows: | Domain | Port | | ------------------------ | ------ | | `appsignal-endpoint.net` | `6514` | ## Structured messages The `message` part of a syslog message can be formatted either in `JSON`, `Logfmt` or `Plaintext`. Formatting the message in `JSON` or `Logfmt` allows you to add additional (structured) data attributes that can be used to find/filter messages on. For more information about the specifics of message formatting, see our [formatting](/logging/formatting) documentation. # Log Formatting Source: https://docs.appsignal.com/logging/formatting ## Message 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> ### Supported Log Formats * [Plaintext](/logging/formatting#plaintext) * [Logfmt](/logging/formatting/logfmt) * [JSON](/logging/formatting/json) How you can format your logs will vary depending on which configuration you are using with Logging. The table below outlines the currently available configurations and the log formats which they support | Platform | [JSON][json-docs] | [Logfmt][logfmt-docs] | [Plaintext](#plaintext) | | --------------------------------------------------------------------------------- | --------------------- | --------------------- | ----------------------- | | [AWS CloudWatch logs through Amazon Data Firehose](/logging/platforms/cloudwatch) | <Icon icon="check" /> | <Icon icon="check" /> | <Icon icon="check" /> | | [Clever Cloud](/logging/platforms/clevercloud) | <Icon icon="check" /> | <Icon icon="check" /> | <Icon icon="check" /> | | [Gigalixir Log Drain](/logging/platforms/gigalixir) | <Icon icon="xmark" /> | <Icon icon="xmark" /> | <Icon icon="check" /> | | [Heroku Log Drain](/logging/platforms/heroku) | <Icon icon="check" /> | <Icon icon="check" /> | <Icon icon="check" /> | | [HTTP](/logging/endpoints/http) | <Icon icon="check" /> | <Icon icon="check" /> | <Icon icon="check" /> | | [Netlify](/logging/platforms/netlify) | <Icon icon="xmark" /> | <Icon icon="xmark" /> | <Icon icon="check" /> | | [Render](/logging/platforms/render) | <Icon icon="check" /> | <Icon icon="check" /> | <Icon icon="check" /> | | [Scalingo](/logging/platforms/scalingo) | <Icon icon="check" /> | <Icon icon="check" /> | <Icon icon="check" /> | | [Syslog](/logging/endpoints/syslog) | <Icon icon="check" /> | <Icon icon="check" /> | <Icon icon="check" /> | ## Fixed-format endpoint We have one special endpoint/source, and that's the `http-json` endpoint. This endpoint is intended for customers implementing their own log forwarding solution, or log implementation. This endpoint expects a specific NDJSON format, and will silently ignore any messages that do not match this format. ### Attributes When using [Logfmt][logfmt-docs] or [JSON][json-docs] as your log format, you can add searchable attributes to your logs. Attributes can be any of the following types: * string * integer (e.g. `10`) * double (e.g. `10.01`) * boolean (`true`/`false`) ### Plaintext When specifying Plaintext as your log format, the log line will be used as the message as-is, and AppSignal will not parse attributes from the log line. If you want to have searchable attributes in your application's logs, we recommend formatting your logs in [Logfmt][logfmt-docs] or [JSON][json-docs]. [json-docs]: /logging/formatting/json.html#json [logfmt-docs]: /logging/formatting/logfmt.html [syslog-info]: https://www.rsyslog.com/doc/master/configuration/modules/pmrfc5424.html # JSON Log Formatting Source: https://docs.appsignal.com/logging/formatting/json <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. # Logfmt Log Formatting Source: https://docs.appsignal.com/logging/formatting/logfmt <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> Logfmt is a log format that is easy for humans to read and write, and is supported by AppSignal. It was initially used as the format for the [Heroku Logdrains](/logging/platforms/heroku), and is now used by many other logging providers. Most of our platforms and endpoints support the Logfmt message format, which we'll describe in more detail below. ## Format Logfmt is a key-value format, where each key-value pair is separated by a space. The key and value are separated by an equals sign (`=`). The key-value pairs are appended to the message at the end of the log line. Any key-value pairs that do not follow the Logfmt format are appended to the message of the log line. ### Examples The following examples show how AppSignal parses logs in the Logfmt format: #### Message with attributes <CodeGroup> ```shell Shell theme={null} this is foo=bar duration=10 a value="with spaces" message ``` </CodeGroup> This will be parsed to a log line with the message `"this is a message"`, and the following attributes: `{ "foo": "bar", "duration": 10, "value": "with spaces"}` #### Message with override <CodeGroup> ```shell Shell theme={null} this is foo=bar a duration=10 message message="I am a message" ``` </CodeGroup> This will be parsed to a log line with the message `"I am a message"`, and the following attributes: `{ "foo": "bar", "duration": 10 }`. The rest of the original message is ignored, in favor of the `message` key. #### Attributes only <CodeGroup> ```shell Shell theme={null} foo=bar duration=100 ``` </CodeGroup> This will be parsed to a log line with the message `"foo=bar duration=100"`, and the following attributes: `{ "foo": "bar", "duration": 100 }` ## Formatting Rules * Keys must be alphanumeric. * Keys cannot contain spaces, but may contain full stops (`.`), underscores (`_`) and hyphens (`-`). * Keys may not contain more than 50 characters * Values must start with an alphanumeric character, and may not be longer than 100 characters * No more than 25 attributes per log message. Key value pairs that do not follow these rules are appended to the message of a log. **Key behavior:** * If a key does not have a value, it will be appended to the message field. * 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. # Logging from AppSignal Integrations Source: https://docs.appsignal.com/logging/integrations AppSignal supports logging directly from your application using the AppSignal integration. You do not need to create a log source to send logs using the AppSignal integration. An "application" log source will be created automatically. ## Supported AppSignal Integrations The following AppSignal integrations support logging: * [Ruby](/logging/integrations/ruby) * [Elixir](/logging/integrations/elixir) * [Node.js](/logging/integrations/nodejs) * [Go](/logging/integrations/go) * [Java](/logging/integrations/java) * [PHP](/logging/integrations/php) * [Python](/logging/integrations/python) ## Process monitoring with AppSignal Wrap You can also send the output of any process as logs to AppSignal, using our wrap tool: <CodeGroup> ```shell Shell theme={null} appsignal-wrap my-process-name -- /path/to/my/process ``` </CodeGroup> Learn more about how to use `appsignal-wrap` to send logs to AppSignal in our [Wrap documentation](/wrap#logging). # Logging from Elixir Source: https://docs.appsignal.com/logging/integrations/elixir <VersionRequirements /> This documentation outlines how to configure logging with the AppSignal for Elixir integration. ## Configure Logging <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> You do not need to create a log source to send logs from the AppSignal for Elixir integration. An "application" log source will be created automatically. ### Logger Handler <Compatibility /> You can configure the Erlang `:logger` to use the `Appsignal.Logger.Handler` module as a handler, by calling the `Appsignal.Logger.Handler.add/2` function on your `Application.start/2` callback: <CodeGroup> ```elixir Elixir theme={null} @impl true def start(_type, _args) do Appsignal.Logger.Handler.add("phoenix") end ``` </CodeGroup> The given argument is the group name that describes where you are logging from. This group name can be used in AppSignal to filter your logs. ### Logger Backend <Tip> Starting with Elixir version 1.15, Elixir logger backends are no longer recommended. See the [Logger Handler section](#logger-handler) above for the recommended alternative. </Tip> Instead of using an Elixir logger handler, you can configure the Elixir logger backend to use the `Appsignal.Logger.Backend` module as a backend by placing the code below in the `config/runtime.exs` file: <CodeGroup> ```elixir Elixir theme={null} config :logger, backends: [:console, {Appsignal.Logger.Backend, [group: "phoenix"]}] ``` </CodeGroup> The `group` option describes where you are logging from. This group name can be used in AppSignal to filter your logs. You can also add the backend using the `add_backend/2` function on your `Application.start/2` callback: <CodeGroup> ```elixir Elixir theme={null} @impl true def start(_type, _args) do Logger.add_backend(Appsignal.Logger.Backend, group: "phoenix") end ``` </CodeGroup> ### Elixir Logger To send logs to AppSignal without using the Elixir Logger backend, you can use one of `Appsignal.Logger`'s logging functions and provide it with a `groupname` that defines where you are logging from. For example, if we were logging from a helper for invoicing clients: <CodeGroup> ```elixir Elixir theme={null} Appsignal.Logger.info( "invoice_helper", "Generating invoice for customer 129" ) ``` </CodeGroup> ## Usage ### Sending Logs Like the Elixir/Phoenix logger class, you can define the severity level of your logs by using `fatal`, `error`, `warning`, `info`, and `debug`: <CodeGroup> ```elixir Elixir theme={null} Appsignal.Logger.warning( "app", "Something's gone terribly wrong here" ) ``` </CodeGroup> You can pass custom attributes as the last argument, to send log information that can be used when filtering and querying logs: <CodeGroup> ```elixir Elixir theme={null} Appsignal.Logger.info( "invoice_helper", "Generated invoice for customer #{customer.id}", %{ customer_id: customer.id, invoice_id: invoice.id } ) ``` </CodeGroup> You can query and filter on message contents and attribute values using our [query syntax](/logging/query-syntax). Once configured, the desired attributes will be sent to AppSignal as log tags, and be queryable in the AppSignal logging interface. ## Formats ### Auto detected format <Compatibility /> The AppSignal for Elixir package will automatically detect the log line's format as JSON, Logfmt or plaintext by default, and parse attributes from it. You don't need to manually set the log format, unless it's not being detected properly. Please also [notify us](mailto:support@appsignal.com?subject=Log%20format%20auto%20detection%20not%20working) if this isn't working automatically. <CodeGroup> ```elixir Elixir theme={null} # Plaintext format Appsignal.Logger.info( "invoice_helper", "Generated invoice" ) # Logfmt format Appsignal.Logger.info( "invoice_helper", "Generated invoice invoice_id=A145 for customer customer_id=123" ) # JSON format Appsignal.Logger.info( "invoice_helper", ~s({"message": "Generated invoice for customer", "invoice_id": "A145", "customer_id": "123"}) ) ``` </CodeGroup> ### Logfmt The AppSignal Logger can be explicitly configured to expect the line to be formatted as Logfmt and parse attributes from it. Use this option when using an older AppSignal for Elixir package version, which does not support [automatic format detection](#auto-detected-format). The Logfmt format can be specified when the AppSignal logger is called by adding the `:logfmt` value as the last argument. <CodeGroup> ```elixir Elixir theme={null} Appsignal.Logger.info( "invoice_helper", "Generated invoice invoice_id=A145 for customer customer_id=123", :logfmt ) ``` </CodeGroup> ### JSON The AppSignal Logger can be explicitly configured to expect the line to be formatted as JSON and parse attributes from it. Use this option when using an older AppSignal for Elixir package version, which does not support [automatic format detection](#auto-detected-format). The JSON format can be specified when the AppSignal logger is called by adding the `:json` value as the last argument. <CodeGroup> ```elixir Elixir theme={null} Appsignal.Logger.info( "invoice_helper", ~s({"message": "Generated invoice for customer", "invoice_id": "A145", "customer_id": "123"}), :json ) ``` </CodeGroup> Only primitive non-nested values (numbers, strings, booleans and `null`) will be shown as log attributes. All other attributes will be discarded. ## Filtering Logs You can use [the `ignore_logs` configuration option](/elixir/configuration/options#option-ignore_logs) to ignore log lines based on their message. See [our Ignore Logs guide](/guides/filter-data/ignore-logs) to learn more. ## Need Help? After configuring your Elixir application to send logs, logs should appear in AppSignal. If you are unsure about this step or AppSignal is not receiving any logs, you can always [reach out](mailto:support@appsignal.com) for assistance. We'll help get you back on track! # Logging from Go Source: https://docs.appsignal.com/logging/integrations/go <VersionRequirements /> This documentation outlines how to configure logging with the AppSignal for Go integration. ## Configure Logging <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> You do not need to create a log source to send logs from the AppSignal for Go integration. An "application" log source will be created automatically. The Go integration uses OpenTelemetry's logging capabilities to send logs to AppSignal. ### Stand-alone usage To use logging with OpenTelemetry in Go, you need to set up the logger using OpenTelemetry's logger provider. <CodeGroup> ```go Go theme={null} package main import ( "context" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/log" ) func main() { // Get the logger from the global logger provider loggerProvider := otel.GetLoggerProvider() logger := loggerProvider.Logger("my-app") // Log a message logger.Emit(context.Background(), log.Record{ Severity: log.SeverityInfo, Body: log.StringValue("Log message line"), }) } ``` </CodeGroup> ### Usage with `slog` <Compatibility /> You can configure the standard `slog` package to send structured logs to AppSignal using the OpenTelemetry handler. <CodeGroup> ```go Go theme={null} package main import ( "context" "log/slog" "go.opentelemetry.io/contrib/bridges/otelslog" ) func main() { // Create an OpenTelemetry `slog` handler otelHandler := otelslog.NewHandler("my-app") // Create a `slog` logger with the OpenTelemetry handler logger := slog.New(otelHandler) // Use the logger logger.Info("Log message line") logger.With("user_id", 123).Info("User logged in") logger.Error("An error occurred", "error", "database connection failed") } ``` </CodeGroup> ## Usage ### Sending Logs Using the OpenTelemetry logger directly, you can define the severity level of your logs: <CodeGroup> ```go Go theme={null} package main import ( "context" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/log" ) func main() { loggerProvider := otel.GetLoggerProvider() logger := loggerProvider.Logger("my-app") // Different severity levels logger.Emit(context.Background(), log.Record{ Severity: log.SeverityWarn, Body: log.StringValue("Something went wrong"), }) logger.Emit(context.Background(), log.Record{ Severity: log.SeverityInfo, Body: log.StringValue("Action completed"), }) logger.Emit(context.Background(), log.Record{ Severity: log.SeverityError, Body: log.StringValue("Database connection failed"), }) } ``` </CodeGroup> You can define custom attributes to send log information that can be used when filtering and querying logs: <CodeGroup> ```go Go theme={null} package main import ( "context" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/log" ) func processInvoice(customerID string) { loggerProvider := otel.GetLoggerProvider() logger := loggerProvider.Logger("invoice_helper") logger.Emit(context.Background(), log.Record{ Severity: log.SeverityInfo, Body: log.StringValue("Generating invoice for customer"), Attributes: []log.KeyValue{ log.String("customer_id", customerID), }, }) invoice := generateInvoice(customerID) logger.Emit(context.Background(), log.Record{ Severity: log.SeverityInfo, Body: log.StringValue("Generated invoice for customer"), Attributes: []log.KeyValue{ log.String("customer_id", customerID), log.String("invoice_id", invoice.ID), }, }) } ``` </CodeGroup> You can query and filter on message contents and attribute values from within the [Log Management](/logging/log-management) tool. Once configured, the desired attributes will be sent to AppSignal as log tags, and be queryable in the AppSignal logging interface. ## Filtering Logs You can use [the `ignore_logs` configuration option](/go/configuration#option-ignore_logs) to ignore log lines. See [our Ignore Logs guide](/guides/filter-data/ignore-logs) to learn more. ## Need Help? After configuring your Go application to send logs, logs should appear in AppSignal. If you are unsure about this step or AppSignal is not receiving any logs, you can always [reach out](mailto:support@appsignal.com) for assistance. We'll help get you back on track! # Logging from Java Source: https://docs.appsignal.com/logging/integrations/java <VersionRequirements /> This documentation outlines how to configure logging with the AppSignal for Java integration. ## Configure Logging <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> You do not need to create a log source to send logs from the AppSignal for Java integration. An "application" log source will be created automatically. The Java integration uses OpenTelemetry's logging capabilities to send logs to AppSignal. ### Stand-alone usage To use logging with OpenTelemetry in Java, you need to set up the logger using the OpenTelemetry LoggerProvider. <CodeGroup> ```java Java theme={null} import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.logs.Logger; import io.opentelemetry.api.logs.LoggerProvider; import io.opentelemetry.api.logs.Severity; public class MyApplication { public void logMessages() { // Get the logger from the global logger provider LoggerProvider loggerProvider = GlobalOpenTelemetry.getLoggerProvider(); Logger logger = loggerProvider.get("my-app"); // Log a message logger.logRecordBuilder() .setSeverity(Severity.INFO) .setBody("Log message line") .emit(); } } ``` </CodeGroup> ### Usage with Log4j Log4j is automatically instrumented by the OpenTelemetry Java agent. Logs emitted using Log4j2 will automatically be sent to AppSignal. Context added using `ThreadContext` or within `StructuredDataMessage` logs will be shown as log tags in AppSignal. <CodeGroup> ```java Java theme={null} import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.ThreadContext; import org.apache.logging.log4j.message.StructuredDataMessage; public class MyService { private static final Logger logger = LogManager.getLogger(MyService.class); public void processOrder(String orderId) { // This will be shown as a tag in AppSignal for all log lines ThreadContext.put("order_id", orderId); logger.info("Processing order"); StructuredDataMessage structuredMessage = new StructuredDataMessage( "processing_items", // ID (not shown in AppSignal) String.format("Processing items in order"), // Message "order" // Type (not shown in AppSignal) ); // This will be shown as a tag in AppSignal for this log line structuredMessage.put("item_count", 123); logger.info(structuredMessage); ThreadContext.clearAll(); } } ``` </CodeGroup> ### Usage with `java.util.logging` Java's built-in logging framework, `java.util.logging`, is automatically instrumented by the OpenTelemetry Java agent. Logs emitted using `java.util.logging` will automatically be sent to AppSignal. <CodeGroup> ```java Java theme={null} import java.util.logging.Logger; import java.util.logging.Level; public class MyApplication { private static final Logger logger = Logger.getLogger(MyApplication.class.getName()); public void doSomething() { logger.info("Application started"); logger.log(Level.WARNING, "This is a warning message"); logger.severe("This is an error message"); } } ``` </CodeGroup> ## Usage ### Sending Logs Using the OpenTelemetry logger directly, you can define the severity level of your logs: <CodeGroup> ```java Java theme={null} import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.logs.Logger; import io.opentelemetry.api.logs.LoggerProvider; import io.opentelemetry.api.logs.Severity; public class MyApplication { public void sendLogs() { // Get the logger from the global logger provider LoggerProvider loggerProvider = GlobalOpenTelemetry.getLoggerProvider(); Logger logger = loggerProvider.get("my-app"); // Different severity levels logger.logRecordBuilder() .setSeverity(Severity.WARN) .setBody("Something went wrong") .emit(); logger.logRecordBuilder() .setSeverity(Severity.INFO) .setBody("Action completed successfully") .emit(); logger.logRecordBuilder() .setSeverity(Severity.ERROR) .setBody("Database connection failed") .emit(); } } ``` </CodeGroup> You can define custom attributes to send log information that can be used when filtering and querying logs: <CodeGroup> ```java Java theme={null} import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.logs.Logger; import io.opentelemetry.api.logs.LoggerProvider; import io.opentelemetry.api.logs.Severity; public class InvoiceService { public void generateInvoice(Customer customer) { LoggerProvider loggerProvider = GlobalOpenTelemetry.getLoggerProvider(); Logger logger = loggerProvider.get("invoice_helper"); logger.logRecordBuilder() .setSeverity(Severity.INFO) .setBody("Generating invoice for customer") .setAllAttributes(Attributes.of( AttributeKey.stringKey("customer_id"), customer.getId() )) .emit(); } } ``` </CodeGroup> You can query and filter on message contents and attribute values from within the [Log Management](/logging/log-management) tool. Once configured, the desired attributes will be sent to AppSignal as log tags, and be queryable in the AppSignal logging interface. ## Filtering Logs You can use [the `ignore_logs` configuration option](/java/configuration#option-ignore_logs) to ignore log lines. See [our Ignore Logs guide](/guides/filter-data/ignore-logs) to learn more. ## Need Help? After configuring your Java application to send logs, logs should appear in AppSignal. If you are unsure about this step or AppSignal is not receiving any logs, you can always [reach out](mailto:support@appsignal.com) for assistance. We'll help get you back on track! # Logging from Node.js Source: https://docs.appsignal.com/logging/integrations/nodejs <VersionRequirements /> This documentation outlines how to configure logging with the AppSignal for Node.js integration. ## Configure Logging <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> You do not need to create a log source to send logs from the AppSignal for Node.js integration. An "application" log source will be created automatically. ### Stand-alone usage To use the logger, you need to import AppSignal and set up the logger using the `.logger()` function. The `.logger()` function accepts two arguments: `group` and optionally `severityThreshold`. If `severityThreshold` is not provided, it will default to `info`. <CodeGroup> ```javascript Node.js theme={null} const { Appsignal } = require("@appsignal/nodejs"); const logger = Appsignal.logger("app"); // with a severity threshold: const logger = Appsignal.logger("app", "info"); ``` </CodeGroup> There are six severity levels available `trace`, `debug`, `info`, `log`, `warn`, and `error`, each of them with its own function with the same name. These functions accept two arguments `message` and `attributes`. Attributes is used for metadata and is optional. Messages will only be logged if their severity level is above the severity threshold. <CodeGroup> ```javascript Node.js theme={null} logger.info("Log message line"); logger.debug("User logged in", { user_id: 123 }); ``` </CodeGroup> Note that if the message's severity is below the severity threshold set up when initializing the logger, it will not be sent to AppSignal. You can query and filter on message contents and attribute values using our [query syntax](/logging/query-syntax). #### Using multiple logging backends It's currently not possible to send logs to multiple backends using Node.js' standard logger. For more complex setups, we recommend using a logging library like Winston or Pino. ### Usage with Winston <Compatibility /> If you use Winston to log messages throughout your application, you can use our Winston transport to send those logs to AppSignal. After importing the transport from the AppSignal integration, add it to the list of transports in your Winston logger: <CodeGroup> ```javascript Node.js theme={null} const winston = require("winston"); const { WinstonTransport } = require("@appsignal/nodejs"); const logger = winston.createLogger({ transports: [new WinstonTransport({ group: "app" })], }); ``` </CodeGroup> #### Child Logger You can use a child logger to add additional tags to log messages. You define tags when creating the child logger constant or pass tags as metadata when writing a log message. Say we want greater context in our logs of the actions of a particular user within a specific session. In the below example, a child logger for the `background` group is used to add `sessionID` with the additional `drinkID`, and `paymentID` tags are provided as metadata when creating a log message, and if a group is given to the child, it'll override the one set up in the transport. <CodeGroup> ```javascript Node.js theme={null} const logger = winston.createLogger({...}); const sessionLogger = logger.child({ group: "background", sessionID: user.id, }); sessionLogger.debug("User logged in"); sessionLogger.info("User ordered coffee", { drinkID: 30, paymentID: 20082 }); sessionLogger.debug("User logged out"); ``` </CodeGroup> #### Using multiple logging backends To send logs to both AppSignal's logger and `STDOUT`, add another transport: <CodeGroup> ```javascript JavaScript theme={null} const winston = require("winston"); const { WinstonTransport } = require("@appsignal/nodejs"); const logger = winston.createLogger({ transports: [ new WinstonTransport({ group: "app" }), new winston.transports.Console(), ], }); ``` </CodeGroup> ### Usage with Pino <Compatibility /> If Pino is your preferred logging library, you can use the AppSignal Pino transport to send logs to AppSignal. The group argument will default to "app" if not provided. <CodeGroup> ```javascript Node.js theme={null} import pino from "pino"; const logger = pino({ transport: { targets: [ { target: "@appsignal/nodejs/pino", options: { group: "my-group" } } ], }, }); ``` </CodeGroup> #### Using multiple logging backends To send logs to both AppSignal's logger and `STDOUT`, add another target: <CodeGroup> ```javascript Node.js theme={null} import pino from "pino"; const logger = pino({ transport: { targets: [ { target: "@appsignal/nodejs/pino", options: { group: "my-group" } }, { target: 'pino/file', options: {destination: 1} } ], }, }); ``` </CodeGroup> ## Formats ### Auto detected format <Compatibility /> The AppSignal for Node.js package will automatically detect the log line's format as JSON, Logfmt or plaintext by default, and parse attributes from it. You don't need to manually set the log format, unless it's not being detected properly. Please also [notify us](mailto:support@appsignal.com?subject=Log%20format%20auto%20detection%20not%20working) if this isn't working automatically. <CodeGroup> ```javascript Node.js theme={null} const { Appsignal } = require("@appsignal/nodejs"); // Plaintext format const logger = Appsignal.logger("app", "info"); logger.info("This is about the blog"); // Logfmt format const logger = Appsignal.logger("app", "info"); logger.info("category=blog This is about the blog"); // JSON format const logger = Appsignal.logger("app", "info"); logger.info('{"category": "blog", "message": "This is about the blog"}'); ``` </CodeGroup> ### Logfmt <Compatibility /> The AppSignal Logger can be explicitly configured to expect the line to be formatted as Logfmt and parse attributes from it. Use this option when using an older AppSignal for Node.js package version, which does not support [automatic format detection](#auto-detected-format). The log format can be specified when creating a logger. When initializing the AppSignal logger pass the `"logfmt"` value as the third argument. <CodeGroup> ```javascript Node.js theme={null} const { Appsignal } = require("@appsignal/nodejs"); const logger = Appsignal.logger("app", "info", "logfmt"); logger.info("category=blog this is about the blog"); ``` </CodeGroup> In the example above, a filterable category attribute with the value "blog" will be logged. ### JSON <Compatibility /> The AppSignal Logger can be explicitly configured to expect the line to be formatted as JSON and parse attributes from it. Use this option when using an older AppSignal for Node.js package version, which does not support [automatic format detection](#auto-detected-format). The log format can be specified when creating a logger. When initializing the AppSignal logger pass the `"json"` value as the third argument. <CodeGroup> ```javascript Node.js theme={null} const { Appsignal } = require("@appsignal/nodejs"); const logger = Appsignal.logger("app", "info", "json"); logger.info('{"category": "blog", "message": "this is about the blog"}'); ``` </CodeGroup> In the example above, a filterable category attribute with the value "blog" will be logged. ## Filtering Logs You can use [the `ignoreLogs` configuration option](/nodejs/3.x/configuration/options#option-ignorelogs) to ignore log lines based on their message. See [our Ignore Logs guide](/guides/filter-data/ignore-logs) to learn more. ## Need Help? After configuring your Node.js application to send logs, logs should appear in AppSignal. If you are unsure about this step or AppSignal is not receiving any logs, you can always [reach out](mailto:support@appsignal.com) for assistance. We'll help get you back on track! # Logging From PHP Source: https://docs.appsignal.com/logging/integrations/php <VersionRequirements /> This documentation outlines how to configure logging with the AppSignal for PHP package. ## Configure logging <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> You do not need to create a log source to send logs from the AppSignal for PHP integration. An "application" log source will be created automatically. The AppSignal for PHP package uses OpenTelemetry's logging capabilities to send logs to AppSignal. ### Laravel If you're using the Laravel framework, the AppSignal for PHP package automatically sends your logs to AppSignal. You do not need to configure Monolog directly. ### Symfony If you're using the Symfony framework, the easiest way to send logs to AppSignal is by using the [`MonologBundle`](https://github.com/symfony/monolog-bundle). Install the Monolog auto-instrumentation package. ```shell Shell theme={null} composer require open-telemetry/opentelemetry-logger-monolog ``` Add a service definition for `'appsignal.monolog.handler'` that uses the `Appsignal\Integrations\Monolog\Handler` class. ```yml title="config/services.yaml" theme={null} services: # ... other services appsignal.monolog.handler: class: Appsignal\Integrations\Monolog\Handler factory: ['Appsignal\Integrations\Monolog\Handler', "withLevel"] arguments: ["info"] # configure log level that will reach AppSignal ``` Add `appsignal.monolog.handler` to the Monolog handler stack. ```yml title="config/packages/monolog.yaml" theme={null} monolog: handlers: # other handlers appsignal: type: service id: appsignal.monolog.handler channels: ["app", "event"] # configure which channels to send to AppSignal ``` ### Monolog [Monolog](https://github.com/Seldaek/monolog) is the most popular logging library for PHP. You can use Monolog directly to send logs to AppSignal. Install the Monolog auto-instrumentation package. ```shell Shell theme={null} composer require open-telemetry/opentelemetry-logger-monolog ``` Then add `Appsignal\Integrations\Monolog\Handler` to Monolog's handler stack. ```php PHP theme={null} use Appsignal\Integrations\Monolog\Handler; use Monolog\Logger; $logger = new Logger('app'); $logger->pushHandler(Handler::withLevel('info')); $logger->info('My log message'); ``` ### Stand-alone usage You can also send logs with the stand-alone logger using the `log` helper method from the `Appsignal` base class. This method doesn't require configuration. ```php PHP theme={null} use Appsignal\Appsignal; use Appsignal\Severity; // Log a message Appsignal::log( message: 'Log message line', severity: Severity::INFO, loggerName: 'my-app', attributes: [ 'customer_id' => $customer->id, ], ); ``` Configure Monolog with the OpenTelemetry handler to send logs to AppSignal: ```php PHP theme={null} use Appsignal\Integrations\Monolog\Handler; use Monolog\Logger; // Create Monolog logger with the AppSignal handler $logger = new Logger('app', [Handler::withLevel('info')]); ``` ## Sending logs ### Monolog Using Monolog, you can define the severity level of your logs: ```php PHP theme={null} $logger->warning("Something's gone terribly wrong here"); $logger->info('User action completed successfully'); $logger->error('Database connection failed'); // using Laravel's Log facade Log::warning("Something's gone terribly wrong here"); Log::info('User action completed successfully'); Log::error('Database connection failed'); ``` You can define custom attributes to send log information that can be used when filtering and querying logs: ```php PHP theme={null} $logger->info('Generating invoice for customer', ['customer_id' => $customer->id]); // using Laravel's Log facade Log::info('Generating invoice for customer', ['customer_id' => $customer->id]); ``` ### Stand-alone logger Using the stand-alone logger, you can define the severity level of your logs: ```php PHP theme={null} use Appsignal\Appsignal; use Appsignal\Severity; // Different severity levels Appsignal::log( message: "Something's gone terribly wrong here", severity: Severity::WARN, ); Appsignal::log( message: 'User action completed successfully', severity: Severity::INFO, ); Appsignal::log( message: 'Database connection failed', severity: Severity::ERROR, ); ``` You can define custom attributes to send log information that can be used when filtering and querying logs: ```php PHP theme={null} use Appsignal\Appsignal; use Appsignal\Severity; function processInvoice($customer) { Appsignal::log( message: 'Generating invoice for customer', severity: Severity::INFO, attributes: ['customer_id' => $customer->id], ); } ``` ## Filtering logs You can query and filter on message contents and attribute values from within the [Log Management](/logging/log-management) tool. Once configured, the desired attributes will be sent to AppSignal as log tags, and be queryable in the AppSignal logging interface. ### Structured logging AppSignal supports structured logging out of the box. You can send structured data as log attributes: ```php PHP theme={null} use Appsignal\Appsignal; use Appsignal\Severity; Appsignal::log( message: 'User action completed', severity: Severity::INFO, attributes: [ 'user_id' => $userId, 'action' => 'purchase', 'product_id' => $productId, 'amount' => $amount, 'currency' => 'USD' ], ); // or using Monolog $logger->info('Generating invoice for customer', ['customer_id' => $customer->id]); // or using Laravel's Log facade Log::info('Generating invoice for customer', ['customer_id' => $customer->id]); ``` <Note> You can also configure AppSignal for PHP to ignore specific log lines using [the `ignore_logs` option](/php/configuration#option-ignore_logs). See [our Ignore Logs guide](/guides/filter-data/ignore-logs) to learn more. </Note> ## Need help? After configuring your PHP application to send logs, logs should appear in AppSignal. If you are unsure about this step or AppSignal is not receiving any logs, you can always [reach out](mailto:support@appsignal.com) for assistance. We'll help get you back on track! # Logging from Python Source: https://docs.appsignal.com/logging/integrations/python <VersionRequirements /> This documentation outlines how to configure logging with the AppSignal for Python integration. <Warning> Logging is only available when using [collector mode](/python/configuration/collector), which is an **experimental feature**. </Warning> ## Configure Logging <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> You do not need to create a log source to send logs from the AppSignal for Python integration. An "application" log source will be created automatically. When using [collector mode](/python/configuration/collector), AppSignal automatically instruments Python's built-in `logging` module via OpenTelemetry, attaching a handler to the root logger. ### Disabling logging instrumentation Instrumentation for Python's `logging` module can be disabled using the [`disable_default_instrumentations` configuration option](/python/configuration/options#option-disable_default_instrumentations): <CodeGroup> ```python Python theme={null} # __appsignal__.py appsignal = Appsignal( # ... disable_default_instrumentations=["logging"], ) ``` </CodeGroup> This disables the automatic instrumentation of the `logging` module by attaching a handler to the root logger, meaning that logs sent to Python's `logging` module will no longer be captured by AppSignal. You can still send logs directly using the OpenTelemetry logs API, as described in the [Sending Logs with OpenTelemetry](#sending-logs-with-opentelemetry) section below. #### Attaching handlers manually When automatic instrumentation is disabled, you can attach the OpenTelemetry `LoggingHandler` to specific loggers yourself, rather than relying on AppSignal adding it to the root logger: <CodeGroup> ```python Python theme={null} import logging from opentelemetry.sdk._logs import LoggingHandler handler = LoggingHandler(level=logging.NOTSET) logging.getLogger("myapp").addHandler(handler) ``` </CodeGroup> This gives you control over which loggers send their output to AppSignal. ### Log level Python's `logging` module defaults to `WARNING`, meaning `INFO` and `DEBUG` messages are not captured by default. To capture lower-severity messages, set the root logger level explicitly: <CodeGroup> ```python Python theme={null} import logging logging.root.setLevel(logging.INFO) ``` </CodeGroup> ### Which logs are captured AppSignal captures logs sent to the root logger and any logger that propagates to it. Propagation is controlled by the `propagate` attribute on each logger, which defaults to `True` in Python. Loggers with `propagate=False` will **not** have their messages captured by AppSignal. ## Framework Setup ### Django Django configures some loggers with `propagate=False` by default, which prevents them from reaching AppSignal. Override these in `settings.py` to re-enable propagation: <CodeGroup> ```python Python theme={null} # settings.py LOGGING = { "version": 1, "disable_existing_loggers": False, "handlers": { "console": {"class": "logging.StreamHandler"}, }, "loggers": { "django.server": { "handlers": ["console"], "level": "INFO", "propagate": True, }, "myapp": { "handlers": ["console"], "level": "INFO", "propagate": True, }, }, } ``` </CodeGroup> Setting `"propagate": True` ensures that the logger's messages reach the root logger, where AppSignal's handler is attached. #### Attaching handlers manually Alternatively, you can attach the `LoggingHandler` directly to Django's loggers instead of relying on propagation to the root logger: <CodeGroup> ```python Python theme={null} # settings.py import logging from opentelemetry.sdk._logs import LoggingHandler LOGGING = { "version": 1, "handlers": { "console": {"class": "logging.StreamHandler"}, "appsignal": {"()": LoggingHandler, "level": logging.NOTSET}, }, "loggers": { "django.server": { "handlers": ["console", "appsignal"], "level": "INFO", }, "myapp": { "handlers": ["console", "appsignal"], "level": "INFO", }, }, } ``` </CodeGroup> ### Celery Celery forks worker processes, so AppSignal must be started for each fork. Use the `worker_process_init` signal to reinitialise AppSignal and configure logging in each worker process. See the [Celery instrumentation page](/python/instrumentations/celery) for more details on instrumenting Celery tasks. <CodeGroup> ```python Python theme={null} # tasks.py import logging import appsignal from celery.signals import worker_process_init @worker_process_init.connect(weak=False) def init_worker_logging(*args, **kwargs): appsignal.start() logging.root.setLevel(logging.INFO) logging.getLogger("celery").propagate = True ``` </CodeGroup> ## Sending Logs with OpenTelemetry You can also send logs directly using the OpenTelemetry logs API, without going through Python's `logging` module: <CodeGroup> ```python Python theme={null} from opentelemetry._logs import get_logger_provider from opentelemetry.sdk._logs import SeverityNumber logger_provider = get_logger_provider() logger = logger_provider.get_logger("my-app") logger.emit( logger_provider.get_logger("my-app").create_log_record( body="Log message line", severity_number=SeverityNumber.INFO, ) ) ``` </CodeGroup> ## Need Help? After configuring your Python application to send logs, logs should appear in AppSignal. If you are unsure about this step or AppSignal is not receiving any logs, you can always [reach out](mailto:support@appsignal.com) for assistance. We'll help get you back on track! # Logging from Ruby Source: https://docs.appsignal.com/logging/integrations/ruby <VersionRequirements /> This documentation outlines how to configure logging with your AppSignal for Ruby integration. ## Configure Logging <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> You do not need to create a log source to send logs from the AppSignal for Ruby integration. An "application" log source will be created automatically. ### Rails Logger <Compatibility /> You can configure the Rails framework to send logs to AppSignal in an initializer file like `config/initializers/logging.rb`: <CodeGroup> ```ruby Ruby theme={null} # config/initializers/logging.rb appsignal_logger = Appsignal::Logger.new("rails") Rails.logger = ActiveSupport::TaggedLogging.new(appsignal_logger) ``` </CodeGroup> #### Using multiple logging backends To send logs to both AppSignal's logger and Rails' default logger, use our logger's `.broadcast_to` helper: <CodeGroup> ```ruby Ruby theme={null} # config/initializers/logging.rb appsignal_logger = Appsignal::Logger.new("rails") appsignal_logger.broadcast_to(Rails.logger) Rails.logger = ActiveSupport::TaggedLogging.new(appsignal_logger) ``` </CodeGroup> We do not recommend using Rails' built-in broadcast logger feature, due to compatibility issues when used alongside tagged logging. #### Tagged logging support The use of `ActiveSupport::TaggedLogging` in the above examples enables support for Rails' log tags. For example, if you wish to add the request ID tag to the log messages, add it to the `config.log_tags` array in the `config/application.rb` file: <CodeGroup> ```ruby Ruby theme={null} module TestApp class Application < Rails::Application config.log_tags = [:request_id] end end ``` </CodeGroup> #### Using Lograge <Warning> This Lograge config is not a replacement for the Rails logger config. If you want to report logs from `Rails.logger`, the [Rails logger config steps](#rails-logger) also need to be followed. </Warning> The [Lograge](https://github.com/roidrage/lograge) library is a popular solution for ingesting structured Rails *request* logs. After adding the `lograge` gem, you can configure it in `config/initializers/lograge.rb` to send logs to AppSignal: <CodeGroup> ```ruby Ruby theme={null} Rails.application.configure do config.lograge.enabled = true config.lograge.keep_original_rails_log = true config.lograge.logger = Appsignal::Logger.new( "rails", format: Appsignal::Logger::LOGFMT ) end ``` </CodeGroup> <Tip> Lograge does not support log levels. All logs emitted via Lograge will appear with severity level `INFO` in the AppSignal Logging UI. </Tip> ### Sinatra Logger You can configure Sinatra to send request logs to AppSignal using Rack's CommonLogger middleware. Configure it like shown below. Consider if request logs contain useful information for you, read our [what logs should I store](https://www.appsignal.com/learning-center/what-logs-should-i-store) learning center article. <CodeGroup> ```ruby Ruby theme={null} logger = Appsignal::Logger.new("sinatra") use Rack::CommonLogger, logger ``` </CodeGroup> #### Using multiple logging backends To send logs to both AppSignal's logger and `STDOUT`, use our logger's `.broadcast_to` helper: <CodeGroup> ```ruby Ruby theme={null} logger = Appsignal::Logger.new("sinatra") logger.broadcast_to(Logger.new($stdout)) use Rack::CommonLogger, logger ``` </CodeGroup> ### Sidekiq Logger You can configure Sidekiq to send its logs to AppSignal, including the logs emitted by your background jobs: <CodeGroup> ```ruby Ruby theme={null} Sidekiq.configure_server do |config| config.logger = Appsignal::Logger.new("sidekiq") config.logger.formatter = Sidekiq::Logger::Formatters::WithoutTimestamp.new end ``` </CodeGroup> #### Using multiple logging backends To send logs to both AppSignal's logger and `STDOUT`, use our logger's `.broadcast_to` helper: <CodeGroup> ```ruby Ruby theme={null} Sidekiq.configure_server do |config| config.logger = Appsignal::Logger.new("sidekiq") config.logger.broadcast_to(Logger.new($stdout)) config.logger.formatter = Sidekiq::Logger::Formatters::WithoutTimestamp.new end ``` </CodeGroup> ### Ruby Logger To send logs to AppSignal as you would with Ruby's `Logger` class, you will need to create an instance of `Appsignal::Logger` and provide it with a `groupname` that defines where you are logging from, for example, if we were logging from a helper for invoicing clients: <CodeGroup> ```ruby Ruby theme={null} logger = Appsignal::Logger.new("invoice_helper") ``` </CodeGroup> #### Using multiple logging backends To send logs to both AppSignal's logger and `STDOUT`, use our logger's `.broadcast_to` helper: <CodeGroup> ```ruby Ruby theme={null} logger = Appsignal::Logger.new("invoice_helper") logger.broadcast_to(Logger.new($stdout)) ``` </CodeGroup> ### Semantic Logger The [Semantic Logger](https://logger.rocketjob.io/) library provides a comprehensive logging solution for Ruby and Rails applications. After adding the `semantic_logger` gem, you can configure it to send logs to AppSignal as follows: <CodeGroup> ```ruby Ruby theme={null} appsignal_logger = Appsignal::Logger.new("rails", format: Appsignal::Logger::LOGFMT) SemanticLogger.add_appender(logger: appsignal_logger, formatter: :logfmt) ``` </CodeGroup> #### Using multiple logging backends To send logs to both AppSignal's logger and `STDOUT`, add another appender using the `add_appender` method: <CodeGroup> ```ruby Ruby theme={null} appsignal_logger = Appsignal::Logger.new("rails", format: Appsignal::Logger::LOGFMT) SemanticLogger.add_appender(logger: appsignal_logger, formatter: :logfmt) SemanticLogger.add_appender(io: $stdout) ``` </CodeGroup> ## Usage ### Sending Logs Like the Ruby/Rails `Logger` class, you can define the severity level of your logs by using `fatal`, `error`, `warn`, `info`, and `debug`: <CodeGroup> ```ruby Ruby theme={null} logger.warn("Something went wrong") ``` </CodeGroup> You can define custom attributes to send log information that can be used when filtering and querying logs: <CodeGroup> ```ruby Ruby theme={null} logger = Appsignal::Logger.new("invoice_helper") logger.info("Generating invoice for customer", { customer_id: @customer.id }) invoice = generate_invoice(@customer) logger.info("Generated invoice for customer", { customer_id: @customer.id, invoice_id: invoice.id }) ``` </CodeGroup> You can query and filter on message contents and attribute values using our [query syntax](/logging/query-syntax). Once configured, the desired attributes will be sent to AppSignal as log tags, and be queryable in the AppSignal logging interface. ### Default Logger Attributes <Compatibility /> When initializing the AppSignal logger, you can provide default attributes that will be included in all log messages: <CodeGroup> ```ruby Ruby theme={null} logger = Appsignal::Logger.new("invoice_helper", attributes: { customer_id: @customer.id }) ``` </CodeGroup> The attributes provided when initializing the logger will be included in all log messages sent from that logger instance. Attributes provided with the log message will be merged with the default logger attributes. <CodeGroup> ```ruby Ruby theme={null} logger = Appsignal::Logger.new("invoice_helper", attributes: { customer_id: @customer.id }) # This log message will contain the `customer_id` attribute: logger.info("Generating invoice for customer") invoice = generate_invoice(@customer) # This log message will contain the `customer_id` and `invoice_id` attributes: logger.info("Generated invoice for customer", { invoice_id: invoice.id }) ``` </CodeGroup> When both the logger and the log message provide the same attribute, the log message's attribute will override the default logger attribute. ## Formats ### Auto detected format <Compatibility /> The AppSignal for Ruby gem will automatically detect the log line's format as JSON, Logfmt or plaintext by default, and parse attributes from it. You don't need to manually set the log format, unless it's not being detected properly. Please also [notify us](mailto:support@appsignal.com?subject=Log%20format%20auto%20detection%20not%20working) if this isn't working automatically. <CodeGroup> ```ruby Ruby theme={null} logger = Appsignal::Logger.new("group") # Plaintext format logger.info("This is about the blog") # Logfmt format logger.info("category=blog This is about the blog") # JSON format logger.info('{"category": "blog", "message": "This is about the blog"}') ``` </CodeGroup> ### Logfmt <Compatibility /> The AppSignal Logger can be explicitly configured to expect the line to be formatted as Logfmt and parse attributes from it. Use this option when using an older AppSignal for Ruby gem version, which does not support [automatic format detection](#auto-detected-format). The log format can be specified when creating a logger. When initializing the AppSignal logger pass the Logfmt constant in the format option. <CodeGroup> ```ruby Ruby theme={null} logger = Appsignal::Logger.new("group", format: Appsignal::Logger::LOGFMT) logger.info("category=blog This is about the blog") ``` </CodeGroup> In the example above, a filterable category attribute with the value "blog" will be logged. ### JSON <Compatibility /> The AppSignal Logger can be explicitly configured to expect the line to be formatted as JSON and parse attributes from it. Use this option when using an older AppSignal for Ruby gem version, which does not support [automatic format detection](#auto-detected-format). The log format can be specified when creating a logger. When initializing the AppSignal logger pass the JSON constant in the format option. <CodeGroup> ```ruby Ruby theme={null} logger = Appsignal::Logger.new("group", format: Appsignal::Logger::JSON) logger.info('{"category": "blog", "message": "This is about the blog"}') ``` </CodeGroup> In the example above, a filterable category attribute with the value "blog" will be logged. ## Filtering Logs You can use [the `ignore_logs` configuration option](/ruby/configuration/options#option-ignore_logs) to ignore log lines. See [our Ignore Logs guide](/guides/filter-data/ignore-logs) to learn more. ## Need Help? After configuring your Ruby application to send logs, logs should appear in AppSignal. If you are unsure about this step or AppSignal is not receiving any logs, you can always [reach out](mailto:support@appsignal.com) for assistance. We'll help get you back on track! # Log Management Source: https://docs.appsignal.com/logging/log-management <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> <img alt="Screenshot of expanded log" /> Once AppSignal Logging is successfully configured, you'll be able to see logs for all of your sources from within the AppSignal application. You can filter and query logs and expand specific logs for their trace data. When viewing your logs you can: * [Filter and Query Logs](#filter-and-query-logs) * [Copy Log Meta Data as JSON](#copy-log-meta-data-as-json) * [Share Log](#share-log) * [View What Happened Here](#what-happened-here) * [Time Detective](#time-detective) * [View Live Trail](#live-trail) #### Filter and Query Logs Use the "Source" drop down to filter which sources you see the logs for. Use the "Severity" drop down to filter the severity of logs Filtering and querying are further explained in the [Query Syntax](/logging/query-syntax) section of this guide. #### Copy Log Meta Data As JSON Expand a log by pressing the "+" button, click "Copy as JSON". Meta data will automatically be copied to your clipboard as a valid JSON object. #### Share Log Click "Copy link to log line" and a link to this log line will automatically be copied to your clipboard. <Tip> Only users within your AppSignal Organization will be able to access the logs via this link </Tip> #### What Happened Here Want to see a snapshot of your application's metric at the exact time the log line was written? Click "What Happened Here" #### Time Detective Use the "Time Detective" button to investigate application wide data at the time a log line was written. #### Live Trail Clicking "Go to live" will take you to a live trail of your logs. ## Managing Sources To modify a source go to AppSignal > Logging > Sources and click "Manage source" <img alt="Screenshot of Source Management" /> When managing a source, you can: * [Edit Source](#edit-source) * [Remove Source](#remove-source) ### Edit Source To edit the source click "Edit source" in the top right corner of the screen. You can edit the following source attributes: * Name * Platform (currently limited to syslog) * Format Changing the log format only applies to new log lines. The attributes and message of existing log lines will not change. ### Remove Source Deletion is permanent and will revoke the API key used for that source. Before removing a log source, we recommend ensuring that the source is no longer sending logs to AppSignal so that your application is not making unnecessary calls to third parties. Before removing the log source in AppSignal, remove the rsyslog configuration file for this log source (located in `etc/rsyslog.d`) and restart rsyslog with the below command. ```bash Bash theme={null} /etc/rc.d/init.d/systemctl restart rsyslogd ``` <img alt="Screenshot of confirm deletion alert" /> To remove a source click "Remove source" from the Source Management page. When prompted to confirm removal read the dialogue box carefully and click "Yes, delete this". The source will be deleted. # Long-Term Log Storage Source: https://docs.appsignal.com/logging/long-term-log-storage <Tip> Long-Term Log Storage is a paid-for Business Add-On. Please [contact us](mailto:support@appsignal.com) for more information, see our [Business Add-Ons documentation](/support/business-add-ons). </Tip> Long-term Log Storage allows you to export and store your AppSignal logs in S3-compatible storage. You need a paid-for Business Add-On to use this feature. AppSignal will continue to store your logs for 30 days. Follow the following steps to configure Long-Term Log Storage: 1. [Ensure you have all requirements](#requirements) 2. [Configure S3 Storage](#configure-s3-storage) 3. [Add storage to log source](#add-storage-to-log-source) ## Requirements To set up Long Term Log Storage you will need: * [The Long-Term Log Storage Business Add-On](/support/business-add-ons#long-term-log-storage) * S3-Compatible Storage ## Configure S3 Storage You will need S3-compatible storage to use Long-Term Log Storage. We have documented the steps for: * [AWS S3 Storage](#configuring-aws-s3-storage) * [DigitalOcean Spaces](#configuring-digitalocean-spaces) If you are using a different service, please read our [Configuring Other S3 Compatible Storage Service](#configuring-other-s3-compatible-storage-services) section. <Tip> If you plan to use the same bucket and credentials to export multiple log sources, make sure to include a unique path for each log source. This will prevent logs from different sources attempting to overwrite each other. </Tip> ### Configuring AWS S3 Storage Follow the following steps to configure AWS S3 storage for Long Term Log Storage: 1. **[Create a new S3 bucket and retrieve it's URL.](https://s3.console.aws.amazon.com/s3/bucket/create)** You will need to provide AppSignal with the bucket's URL. You can generate this URL with the following pattern: `https://s3.[region-code].amazonaws.com/[bucket-name]`, replacing `[region]` and `[bucket-name]` respectively. 2. **[Create a new user with Programmatic access and `read/write` access to the bucket you intend to store logs in.](https://console.aws.amazon.com/iam/home#/users\$new?step=details)** You will need to provide AppSignal with the user's `access key ID` and `access secret key`. An example IAM policy is: <CodeGroup> ```json JSON theme={null} "Statement": [ { "Effect": "Allow", "Action": [ "s3:PutObject", "s3:GetObject", "s3:ListBucket" ], "Resource": [ "arn:aws:s3:::<bucket_name>", "arn:aws:s3:::<bucket_name>/*" ] } ] ``` </CodeGroup> 3. **[Add storage to log source.](#add-storage-to-log-source)** ### Configuring DigitalOcean Spaces Follow the following steps to configure DigitalOcean Spaces for Long Term Log Storage: 1. **[Create a new space with `Restrict File Listing` and retrieve it's URL.](https://cloud.digitalocean.com/spaces/new)** You will need to provide AppSignal with the spaces' URL. You can generate this URL with the following pattern: `[region].digitaloceanspaces.com/[spacename]`, replacing `[region]` and `[spacename]` respectively. 2. **[Generate a new DigitalOcean API token key.](https://cloud.digitalocean.com/account/api/tokens)** You will need to provide AppSignal with the key's `access key` and `secret key`. 3. **[Add storage to log source.](#add-storage-to-log-source)** ### Configuring Other S3-Compatible Storage Services Follow the following steps to configure S3-compatible storage services for Long Term Log Storage: 1. **Create a new bucket and retrieve its URL.** You will need to provide AppSignal with the bucket's URL, see your S3 storage service's documentation for details on where to locate this. 2. **Create a new access key.** You will need to provide AppSignal with the key's `access key` and `secret key`, see your S3 storage service's documentation for details on how to generate this. 3. **[Add storage to log source.](#add-storage-to-log-source)** ## Add Storage To Log Source Before adding storage to a log source, make sure you've followed the storage set-up steps and have the following information: * Bucket URL * `access key` and `secret key` Once you have this information to hand, follow the following steps to add your S3 storage to your desired log source. 1. Navigate to Log Sources and click "Add storage" on the desired log source: <img alt="Image of log sources with Add storage link" /> 1. Provide AppSignal with your `buckets URL`, `access key` and `secret key` and complete setup by clicking `Send long-term storage request`. <img alt="Form for adding long term storage" /> Once set-up is complete, AppSignal will enqueue a storage job to begin writing log data to your S3 bucket. Each job will create a file in your S3 bucket with the following filename and format: `/yyyy-mm/yyyy-mm-ddThhmmss-yyyy-mm-ddThhmmss.json.gz` For example: `https://s3.com/2015-01/2015-01-01T100000-2015-01-02T110000.json.gz` You can read more about storage jobs in the [Storage Jobs and Exceptions](#storage-jobs-and-exceptions) section. ## Storage Jobs and Exceptions In this section, you can learn more about the writing of logs to S3 storage via storage jobs, and how AppSignal handles job exceptions. ### Storage jobs Storage jobs are run every hour. Each job writes **one hour** of log data from **25 hours ago**. For example, a job that runs on `12/01/2024` at `10:00`, will write a file of logs from: `11/01/2024` that were created between `09:00` and `09:59:59` to your S3 storage. This ensures that any log lines, that may have been delayed, are included in the storage job. If a job is successful, a job for the next hour of data is enqueued and your source's long-term storage will have the status of "Running". You can view and manage storage jobs from the "Manage source" page. <img alt="Source overview page" /> ### Exceptions If a storage job fails, AppSignal will attempt to re-run the storage job each hour, for 24 hours (so 24 attempts). If after 24 attempts AppSignal is unable to complete the storage job, we will notify you of a `failed` job. ### Restoring A Failed Job When a Log source has a storage job with a `failed` status, AppSignal will stop enqueueing new jobs. Clicking on the `failed` status will display the error AppSignal encountered when trying to run the storage job. <img alt="Source storage job error message" /> You will need to manually verify the Log source's settings to re-try the job, this can be done via the "Manage source" page. Once verified, AppSignal will re-try the job. If this succeeds, AppSignal will resume hourly storage jobs and your source's long-term storage will have the status of "Running". <Warning> You have until 48 hours before your AppSignal log retention cut-off to store logs with your S3 storage. For example, with 30 days of retention, you would have until `10:00` on `29/01/2024` to store logs from `09:00-09:59:59` on `01/01/2024`. </Warning> ## Removing storage To remove long-term storage from a source navigate to the source's "Manage source" page and click "Remove storage". Once confirmed AppSignal will remove the source's storage and delete the source's storage job history. Log data already stored in your storage will not be deleted. # Log-based metrics Source: https://docs.appsignal.com/logging/metrics Turn data from your logs into metrics you can chart, alert on, and group across your application. If you have indexed logs in AppSignal, you can generate metrics from them directly in the Explore view. Use these log-based metrics to track important signals over time, set up triggers, or add them to dashboards, all without changing your application code or leaving your log exploration workflow. Use log metrics to count how often an event happens, track the latest value of a numeric field, or follow its average and percentiles over time. When you spot something worth tracking in your logs, you can turn it into a metric without leaving the Logs page. The query, severity, and log source you've used to narrow your logs carry into the metric, so the filtering work you've already done is what defines what the metric tracks. Once the metric is saved, you can add it to a dashboard or use it in a trigger in the same flow. ## Create a metric from a log line The fastest way to create a metric is from a log line that already shows the data you want to track. 1. Open the **Logs** page for your app. 2. Use the query bar to filter the log lines that match the event you want to measure. 3. Select a log line in the table to open the **Log details** panel. 4. In the **Actions** section, select **Create a metric**. 5. The Create metric overlay opens with the **Log source**, **Severity**, and **Query** fields prefilled from the log line. <img alt="Log details panel with the Create a metric action" /> ## Configure the metric In the **Define metric** panel, fill in the fields that describe what you want to measure. As you change any field, the **Data preview** on the right updates so you can confirm the metric returns the data you expect. * **Metric name**: A unique name for the metric, used when you reference it on dashboards and triggers. See [metric naming](#metric-naming) for the rules and recommendations. * **Log source**: The log source the metric draws events from. * **Severity**: Filter by severity, or select **all** to include every level. * **Query**: The query string used to match log lines. Same syntax as the Logs page. * **Metric type**: Count, Gauge, or Measurement. See [metric types](#metric-types). * **Field to measure**: For Gauge and Measurement metrics, the numeric field to track β€” like the duration or size of each event, instead of counting occurrences. * **Group by tag**: Split the metric by a tag to get a separate series per unique value (for example, group by `hostname` to get one series per server). When you finish, select **Create metric** to save. ### Metric naming We recommend naming your metrics something easily recognizable. Metric names only support numbers, letters, dots and underscores (`[a-z0-9._]`) as valid characters. Any other characters will be replaced with an underscore by our processor. Some examples of good metric names are: * `database_size` * `account_count` * `users.count` * `notifier.failed` * `orders.request.duration` <Warning> **Note**: We **do not** recommend adding dynamic values to your metric names like so: `eu.database_size`, `us.database_size` and `asia.database_size`. This creates multiple metrics that serve the same purpose. Instead we recommend using **Group by tag** for this. </Warning> ## Metric types The metric type defines how AppSignal aggregates the data over time. The **Field to measure** field appears for Gauge and Measurement only, since Count just counts matching log lines. ### Count The total number of matching events in a given time frame. Use this for events like errors, sign-ups, or job retries. Count does not require a **Field to measure** β€” it just counts every log line matching your query. <img alt="Create metric overlay with the Count chart preview" /> ### Gauge The current value at the moment. Use this for values that move up and down, such as an active connection count. <img alt="Create metric overlay with the Gauge chart preview" /> ### Measurement Averages, counts, and percentiles for a numeric field over time. Use this when the distribution matters, such as request duration. Measurement persists the mean, count, and 90th/95th percentiles of the **Field to measure** for each interval. ## Preview your metric The **Data preview** panel has two tabs that let you confirm the metric returns the data you expect before saving. ### Chart A live chart of the metric for the selected time range. The chart preview supports selecting multiple log sources and severities, and updates as you change any field in the **Define metric** panel. Use the time-range selector below the chart to switch between **Last 24 hours**, **Last 48 hours**, and **Last 7 days**. <img alt="Create metric overlay with the chart time-range selector open" /> ### Log lines The log lines that match your current query. When a **Field to measure** is set, that field is shown as a highlighted column so you can confirm the values before saving. <img alt="Create metric overlay with the log lines preview" /> ## Choose what to do next After you save a metric for the first time, AppSignal asks what you want to do with it: * **Add to dashboard**: Add the metric to a chart on an existing dashboard. * **Create a trigger**: Open the trigger creation flow with the metric prefilled. * **Edit metric**: Reopen the overlay to refine the configuration. For follow-up metrics, AppSignal shows a confirmation toast instead. You can still reach the same options from the **Metrics** page. A new metric may take a moment to start collecting data, so a dashboard or trigger created right after may briefly show a "no data yet" warning. ## Edit a metric 1. Open the **Metrics** page from the **Logging** side menu. 2. Find the metric and select **Edit** from the three-dot menu. 3. Adjust the **Severity**, **Query**, **Field to measure**, or **Group by tag** fields. 4. Select **Update metric** to save. The **Metric name** and **Metric type** are read-only when editing. To change either, create a new metric. From the row menu on the **Metrics** page, you can also add the metric to a dashboard, create a trigger from it, or delete it. The **Modified by** column shows who last updated each metric, so you can see at a glance which team member made the most recent change. ## Example: track request duration * **Metric name**: `orders.request.duration` * **Log source**: application * **Query**: `path=/api/orders` * **Metric type**: Measurement * **Field to measure**: `duration_ms` * **Group by tag**: `hostname` This metric reports the average, count, and percentiles of `duration_ms` for requests to `/api/orders`, with one series per host. # Migrating to the new query syntax Source: https://docs.appsignal.com/logging/migration We're about to migrate you to the new query syntax for logging. This will allow you to query your logs more efficiently. The new query syntax has impact on the following logging areas. Take a look at each of them to see the notable changes: * [Query language](#query-language) * [Saved views](#saved-views) * [Log triggers](#log-triggers) * [Long term storage](#long-term-storage) Make sure you are aware of all these changes, and [contact support](mailto:support@appsignal.com) to start the migration process. ## Query Language The query language changes in a few significant ways. Here are some of the most notable changes: 1. **No more `attributes.` prefix** β€” Custom attributes can now be queried directly. Instead of `attributes.user_id_int=12345`, simply use `user_id=12345`. 2. **No more type suffixes** β€” You no longer need to append `_int`, `_string`, or `_double` to attribute names. The query engine automatically determines the correct type based on the operator you use. 3. **Nested JSON support** β€” Query nested objects using dot notation: `user.email="user@example.com"` and array elements by index: `user.roles.0=admin`. 4. **OR logic and parentheses** β€” Build complex queries with explicit `OR` operators and parentheses for grouping: `severity=error AND (hostname=web-1 OR hostname=web-2)`. 5. **List syntax replaced** β€” The `field=[value1, value2]` syntax is replaced with OR statements, which is more flexible and supports all operators, not just exact matches. For example: **Old syntax:** <CodeGroup> ```sh Shell theme={null} message:"API request" attributes.user_id_int=12345 severity=[info, warn] ``` </CodeGroup> **New syntax:** <CodeGroup> ```sh Shell theme={null} message:"API request" user.id=12345 (severity=info OR severity=warn) ``` </CodeGroup> For complete details on the new syntax, see our [query syntax documentation](/logging/query-syntax). To reference the old syntax, see the [legacy query syntax documentation](/logging/legacy-query-syntax). ## Saved Views Your saved views will be updated to the new query syntax. After the migration, check the views for any issues. ## Log Triggers Your log triggers will be updated to the new query syntax. After the migration, check the triggers for any issues. Triggers that were open, will be closed, and you'll get new issues after the migration. ## Long Term Storage We're making a change to the output of the [long term storage](/logging/long-term-log-storage) exports. Instead of an attributes field that contains a 1-dimensional map of attribute key-values, we'll export a Stringified JSON object with all the attributes. For example: **Old output:** <CodeGroup> ```json JSON theme={null} { "timestamp": "1970-01-01 00:04:00.000", "source_id": "source-json", "hostname": null, "group": "group", "severity": "info", "message": null, "attributes": { "user.name": "alice", "user.id": "123", "request_id": "abc-123", "status_code": "200", "response_time": "45.67", "success": "true" } } ``` </CodeGroup> **New output:** <CodeGroup> ```json JSON theme={null} { "timestamp": "1970-01-01 00:04:00.000", "hostname": null, "group": "group", "severity": "info", "message": null, "source_id": "source-json", "attributes": "{\"user\": {\"name\":\"alice\", \"id\":\"123\"},\"request_id\":\"abc-123\",\"status_code\":200,\"response_time\":45.67,\"success\":true}" } ``` </CodeGroup> # Supported Platforms Source: https://docs.appsignal.com/logging/platforms ## Supported Platforms AppSignal Log Management supports the following platforms: * AWS CloudWatch logs through Amazon Data Firehose * [Manual setup](/logging/platforms/cloudwatch) * [CloudFormation setup](/logging/platforms/cloudwatch-cloudformation) * [Clever Cloud](/logging/platforms/clevercloud) * [Gigalixir Log Drain](/logging/platforms/gigalixir) * [Heroku](/logging/platforms/heroku) * [Netlify](/logging/platforms/netlify) * [Render](/logging/platforms/render) * [Scalingo](/logging/platforms/scalingo) * [Vector](/logging/platforms/vector) * [Vercel](/vercel/logs) ### Supported Log Endpoints If your platform is not listed, you can use one of the following endpoints to send log lines to AppSignal manually: * [HTTP](/logging/endpoints/http) * [HTTP-JSON](/logging/endpoints/http-json) * [HTTP-Syslog](/logging/endpoints/http-syslog) * [Syslog](/logging/endpoints/syslog) ### Supported AppSignal Integrations The following AppSignal Integrations support AppSignal Logging: * [Ruby](/logging/integrations/ruby) * [Elixir](/logging/integrations/elixir) * [Node.js](/logging/integrations/nodejs) * [Go](/logging/integrations/go) * [Java](/logging/integrations/java) * [PHP](/logging/integrations/php) * [Python](/logging/integrations/python) # Clever Cloud Source: https://docs.appsignal.com/logging/platforms/clevercloud AppSignal can automatically ingest logs via Clever Cloud Log Drain. To configure this, you will need to create a new logdrain in Clever Cloud's [CLI](https://www.clever-cloud.com/doc/getting-started/cli/). To set up your log drain, copy and paste the below command: <CodeGroup> ```shell Shell theme={null} clever drain create HTTP "https://appsignal-endpoint.net/logs/syslog?api_key=YOUR_LOG_SOURCE_API_KEY" ``` </CodeGroup> Replace `YOUR_LOG_SOURCE_API_KEY` with the key provided when [creating a log source](/logging/configuration#creating-a-log-source). When created, logs should appear in AppSignal. If you still cannot see any logs, please [contact us](mailto:support@appsignal.com) for support. You can find more information on Clever Cloud's drains in their [Logs Management](https://www.clever-cloud.com/doc/administrate/log-management/#exporting-logs-to-an-external-tools) documentation. # Send CloudWatch logs to AppSignal through Amazon Data Firehose Source: https://docs.appsignal.com/logging/platforms/cloudwatch <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> Complete the following steps to send CloudWatch logs to AppSignal through Amazon Data Firehose (formerly Kinesis Data Firehose): 1. [Create a log source](#create-a-log-source) 2. [Set up an S3 bucket for failed deliveries](#set-up-an-s3-bucket-for-failed-deliveries) 3. [Set up an IAM role for Data Firehose](#set-up-an-iam-role-for-data-firehose) 4. [Create a Firehose delivery stream](#create-a-firehose-delivery-stream) 5. [Set up an IAM role for CloudWatch](#set-up-an-iam-role-for-cloudwatch) 6. [Create a CloudWatch log subscription](#create-a-cloudwatch-log-subscription) Before you start, have the following information ready: * Your log source's [API key](https://appsignal.com/redirect-to/app?to=logs/sources). If you do not have a log source yet, [create a new log source](/logging/configuration#creating-a-log-source) first. * AWS account ID * AWS region * S3 bucket name for failed delivery storage * Data Firehose stream name * IAM role name for the S3 bucket * IAM role name for the CloudWatch subscription ## Create a log source Create a log source before proceeding. See [Logging configuration](/logging/configuration#creating-a-log-source) for instructions. ## Set up an S3 bucket for failed deliveries Amazon Data Firehose requires an S3 bucket to store records that fail to deliver. Create an S3 bucket through the AWS Console or CLI before proceeding, you can't create a Firehose delivery stream without one. ## Set up an IAM role for Data Firehose Create an IAM role that allows Data Firehose to write to the S3 bucket and, optionally, to CloudWatch Logs for delivery error logging. Use the following trust policy: <CodeGroup> ```json JSON theme={null} { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "firehose.amazonaws.com" }, "Action": "sts:AssumeRole" } ] } ``` </CodeGroup> Assign the following permissions policy to the role as an inline policy. <Note> See [Adding IAM identity permissions](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_manage-attach-detach.html) for instructions on creating inline policies for IAM roles. </Note> <CodeGroup> ```json JSON theme={null} { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:AbortMultipartUpload", "s3:GetBucketLocation", "s3:GetObject", "s3:ListBucket", "s3:ListBucketMultipartUploads", "s3:PutObject" ], "Resource": [ "arn:aws:s3:::<FIREHOSE_S3_BUCKET>", "arn:aws:s3:::<FIREHOSE_S3_BUCKET>/*" ] }, { "Effect": "Allow", "Action": ["logs:PutLogEvents"], "Resource": [ "arn:aws:logs:<AWS_REGION>:<AWS_ACCOUNT_ID>:log-group:<FIREHOSE_LOG_GROUP>:*" ] } ] } ``` </CodeGroup> Replace the placeholders with your own values: * `<AWS_ACCOUNT_ID>` β€” your AWS account ID. * `<AWS_REGION>` β€” the region your Firehose stream will run in. * `<FIREHOSE_S3_BUCKET>` β€” the S3 bucket you created in the previous step. * `<FIREHOSE_LOG_GROUP>` β€” the log group Firehose uses for **its own delivery error logs** (separate from the log group you want to stream to AppSignal). AWS uses the convention `/aws/kinesisfirehose/<FIREHOSE_STREAM_NAME>`, so decide your Firehose stream name now β€” you'll reuse it in the next step. If you don't plan to enable error logging on the Firehose stream, you can omit the `logs:PutLogEvents` statement entirely. <Note> See [Controlling access with Amazon Data Firehose](https://docs.aws.amazon.com/firehose/latest/dev/controlling-access.html) for more on the permissions Data Firehose requires. </Note> ## Create a Firehose delivery stream 1. Open the Amazon Data Firehose console and select **Create Firehose stream**. 2. Select **Direct PUT** as the source. 3. Select **HTTP Endpoint** as the destination. 4. Under "Transform records", leave data transformation turned off. 5. Enter the following URL as the **HTTP endpoint URL**: <CodeGroup> ```shell Shell theme={null} https://appsignal-endpoint.net/logs/aws-kinesis ``` </CodeGroup> 6. Enter your AppSignal log source API key from [creating a log source](/logging/configuration#creating-a-log-source) as the **Access key**. This is an AppSignal key, not an AWS access key. 7. Under "Content encoding", enable **GZIP**. 8. Under "Backup settings", select the S3 bucket you created in the previous step. 9. Under "Advanced settings > Service access", select **Choose existing IAM role** and choose the IAM role you created in the previous step. 10. (Optional) Under "Advanced settings > Amazon CloudWatch error logging", enable error logging to use the `logs:PutLogEvents` permission you granted in the previous step. 11. Use the same Firehose stream name you referenced when setting up the IAM role, then select **Create Firehose stream**. To verify the connection, you can use the **Test with demo data** button in the Firehose console. The stock-ticker JSON payloads it sends appear in AppSignal under **Logging** as individual log lines β€” a useful end-to-end check before you hook up real log groups. You can also watch `DeliveryToHttpEndpoint.Success` climb on the Firehose stream's **Monitoring** tab. ## Set up an IAM role for CloudWatch Create an IAM role that allows CloudWatch to send logs to the Firehose delivery stream. Use the following trust policy: <CodeGroup> ```json JSON theme={null} { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "logs.<AWS_REGION>.amazonaws.com" }, "Action": "sts:AssumeRole" } ] } ``` </CodeGroup> Assign the following permissions policy to the role as an inline policy. <Note> See [Adding IAM identity permissions](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_manage-attach-detach.html) for instructions on creating inline policies for IAM roles. </Note> <CodeGroup> ```json JSON theme={null} { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": ["firehose:*"], "Resource": [ "arn:aws:firehose:<AWS_REGION>:<AWS_ACCOUNT_ID>:deliverystream/<FIREHOSE_DELIVERY_STREAM>" ] } ] } ``` </CodeGroup> Replace `<AWS_REGION>`, `<AWS_ACCOUNT_ID>`, and `<FIREHOSE_DELIVERY_STREAM>` with your own values. ## Create a CloudWatch log subscription 1. In the CloudWatch console, navigate to the log group whose logs you want to stream. 2. Open the **Subscription filters** tab. 3. Select **Create Amazon Data Firehose subscription filter**. 4. Choose the Firehose delivery stream from [step 4](#create-a-firehose-delivery-stream) and the IAM role from [step 5](#set-up-an-iam-role-for-cloudwatch). 5. Enter a **Subscription filter name** and select **Start streaming**. After saving the subscription, logs appear in AppSignal under the log source you've configured above. If you see an error saving the subscription, verify that the IAM role in [step 5](#set-up-an-iam-role-for-cloudwatch) uses the correct region, account ID, and delivery stream name. If logs do not appear in AppSignal: * Open your Firehose stream's **Monitoring** tab and check `DeliveryToHttpEndpoint.Success`. The value should stay near 1; a drop or zero indicates AppSignal is rejecting records. * Check the S3 failure bucket from [step 2](#set-up-an-s3-bucket-for-failed-deliveries). Failed records land there, and each object contains the rejection reason. * If records are failing with an authorization error, verify that the **Access key** on the Firehose stream matches your AppSignal log source API key. If you're still stuck, [contact us](mailto:support@appsignal.com) for support. # Stream CloudWatch logs with CloudFormation Source: https://docs.appsignal.com/logging/platforms/cloudwatch-cloudformation <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> You can automate the setup of CloudWatch logs streaming to AppSignal using an AWS CloudFormation template. This creates all the required resources in a single deployment instead of configuring each one manually through the AWS Console. If you prefer to set up each resource manually, see the [CloudWatch logs setup guide](/logging/platforms/cloudwatch). ## Before you start Have the following information ready: * Your log source's [API key](https://appsignal.com/redirect-to/app?to=logs/sources). If you do not have a log source yet, [create a new log source](/logging/configuration#creating-a-log-source) first. * The name of the existing CloudWatch log group you want to stream to AppSignal. * The AWS region where the log group lives. Deploy the stack in the same region and account as the log group. ## What the template creates The CloudFormation template creates the following resources: 1. An **S3 bucket** to store records that fail to deliver, with server-side encryption, public access blocked, a 30-day lifecycle expiration, and a retain-on-delete policy. 2. An **IAM role** that allows Amazon Data Firehose to write failed records to the S3 bucket and to write its own delivery error logs to CloudWatch. 3. A **Firehose delivery stream** that sends logs to the AppSignal endpoint over HTTPS. 4. An **IAM role** that allows CloudWatch Logs to write to the Firehose delivery stream. 5. A **CloudWatch log subscription filter** on your existing log group that forwards log events to the Firehose delivery stream. ## CloudFormation template Copy the following template and save it as `appsignal-cloudwatch-logs.yaml`: <CodeGroup> ```yaml YAML theme={null} AWSTemplateFormatVersion: 2010-09-09 Description: >- Configures a CloudWatch log subscription and Amazon Data Firehose delivery stream to send logs to AppSignal from an existing CloudWatch log group. It must be deployed in the same region and same account as the CloudWatch log group. Implements all the steps from AppSignal documentation all at once: https://docs.appsignal.com/logging/platforms/cloudwatch.html Metadata: AWS::CloudFormation::Interface: ParameterGroups: - Label: default: AppSignal Configuration Parameters: - LogSourceApiKey - Label: default: CloudWatch Configuration Parameters: - CloudWatchLogGroupName ParameterLabels: LogSourceApiKey: default: "Log Source API Key (find at https://appsignal.com/redirect-to/app?to=logs/sources)" CloudWatchLogGroupName: default: "CloudWatch Log Group Name" Parameters: LogSourceApiKey: Type: String Description: Your AppSignal log source API key (39-character hexadecimal string). NoEcho: true MinLength: 39 MaxLength: 39 CloudWatchLogGroupName: Type: String Description: >- Name (not the ARN) of the CloudWatch log group to send to AppSignal. Group logs list: https://console.aws.amazon.com/cloudwatch/home#logsV2:log-groups MinLength: 1 Resources: S3FirehoseEventsBucket: Type: AWS::S3::Bucket DeletionPolicy: Retain Properties: BucketName: !Join - "-" - - "appsignal-firehose" - !Ref AWS::StackName - !Ref AWS::AccountId - !Ref AWS::Region PublicAccessBlockConfiguration: BlockPublicAcls: true BlockPublicPolicy: true IgnorePublicAcls: true RestrictPublicBuckets: true BucketEncryption: ServerSideEncryptionConfiguration: - ServerSideEncryptionByDefault: SSEAlgorithm: AES256 LifecycleConfiguration: Rules: - Id: ExpireFailedDeliveries Status: Enabled ExpirationInDays: 30 FirehoseRole: Type: AWS::IAM::Role Properties: Description: >- Role to allow firehose stream to put events into S3 backup bucket RoleName: !Join - "-" - - "appsignal-firehose" - !Ref AWS::StackName AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: - firehose.amazonaws.com Action: - "sts:AssumeRole" Policies: - PolicyName: !Join - "-" - - "appsignal-firehose" - !Ref AWS::StackName PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - "s3:AbortMultipartUpload" - "s3:GetBucketLocation" - "s3:GetObject" - "s3:ListBucket" - "s3:ListBucketMultipartUploads" - "s3:PutObject" Resource: - !GetAtt S3FirehoseEventsBucket.Arn - !Join ["", [!GetAtt S3FirehoseEventsBucket.Arn, "/*"]] - Effect: Allow Action: - "logs:PutLogEvents" Resource: - !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/kinesisfirehose/appsignal-firehose-${AWS::StackName}:*" FirehoseDeliveryStream: Type: AWS::KinesisFirehose::DeliveryStream Properties: DeliveryStreamName: !Join - "-" - - "appsignal-firehose" - !Ref AWS::StackName DeliveryStreamType: DirectPut HttpEndpointDestinationConfiguration: RequestConfiguration: ContentEncoding: GZIP EndpointConfiguration: Name: AppSignal Url: "https://appsignal-endpoint.net/logs/aws-kinesis" AccessKey: !Ref LogSourceApiKey BufferingHints: IntervalInSeconds: 60 SizeInMBs: 1 RetryOptions: DurationInSeconds: 60 S3Configuration: CompressionFormat: GZIP BucketARN: !GetAtt S3FirehoseEventsBucket.Arn RoleARN: !GetAtt FirehoseRole.Arn RoleARN: !GetAtt FirehoseRole.Arn LogsStreamRole: Type: AWS::IAM::Role Properties: Description: Role to allow stream put into a firehose RoleName: !Join - "-" - - "appsignal-cloudwatch" - !Ref AWS::StackName AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: - !Sub "logs.${AWS::Region}.amazonaws.com" Action: - "sts:AssumeRole" Policies: - PolicyName: !Join - "-" - - "appsignal-firehose" - !Ref AWS::StackName PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - "firehose:*" Resource: - !GetAtt FirehoseDeliveryStream.Arn SubscriptionFilter: Type: AWS::Logs::SubscriptionFilter Properties: LogGroupName: !Ref CloudWatchLogGroupName FilterName: "AppSignal" FilterPattern: "" DestinationArn: !GetAtt FirehoseDeliveryStream.Arn RoleArn: !GetAtt LogsStreamRole.Arn ``` </CodeGroup> <Note> The `logs:PutLogEvents` statement allows Firehose to write its own delivery error logs to CloudWatch. It targets the Firehose error log group (`/aws/kinesisfirehose/<STREAM_NAME>`), which is separate from the log group you want to stream to AppSignal. See [Controlling access with Amazon Data Firehose](https://docs.aws.amazon.com/firehose/latest/dev/controlling-access.html) for more details. </Note> ## Deploy the stack 1. Open the [AWS CloudFormation console](https://console.aws.amazon.com/cloudformation/). 2. Select **Create stack** and choose **With new resources (standard)**. 3. Under **Specify template**, select **Upload a template file** and upload `appsignal-cloudwatch-logs.yaml`. 4. Select **Next**. 5. Enter a stack name, for example `appsignal-cloudwatch-logs`. 6. For **LogSourceApiKey**, enter your log source's API key. 7. For **CloudWatchLogGroupName**, enter the exact name of the log group you want to stream. 8. Select **Next** twice, then check **I acknowledge that AWS CloudFormation might create IAM resources** and select **Submit**. The stack takes a few minutes to create. Once the status shows **CREATE\_COMPLETE**, CloudWatch begins streaming logs to AppSignal. ## Verify the deployment 1. In the AWS Console, search for "CloudFormation" and select **Stacks**. Open your stack and select the **Resources** tab to confirm all resources show **CREATE\_COMPLETE**. 2. In the AWS Console, search for "CloudWatch". In the left sidebar, open your log group and select the **Subscription filters** tab to confirm the `AppSignal` filter is listed. 3. In the AWS Console, search for "Firehose". Open the delivery stream and use the **Test with demo data** function to verify connectivity. 4. In AppSignal, open the [log management screen](/logging/log-management) and confirm log entries from your log group appear there. If logs do not appear after a few minutes, check the S3 bucket for failed delivery records. If you need help, [contact us](mailto:support@appsignal.com). ## Multi-region deployments The template must be deployed in the same region and account as the CloudWatch log group. If you have log groups in multiple regions, deploy a separate copy of this stack in each region. ## Clean up To remove all resources created by this template, delete the stack in the CloudFormation console. The S3 bucket for failed deliveries has a `DeletionPolicy` of `Retain`, so it is kept when the stack is deleted to avoid losing any failed delivery records. Failed delivery records in the bucket are automatically deleted after 30 days by the lifecycle rule. You can delete the bucket manually once you no longer need it. # Gigalixir Log Drain Source: https://docs.appsignal.com/logging/platforms/gigalixir <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> AppSignal can ingest logs via [Gigalixir Log Drain](https://gigalixir.readthedocs.io/en/latest/log.html#). Gigalixir logs use the `Plaintext` format, you can find more information on formatting in our [Log Formatting Documentation](/logging/formatting). ## Check For Existing Log Drains Before creating a new log drain for AppSignal, we recommend checking to see if a drain for AppSignal already exists. You can do so using the following command: <CodeGroup> ```shell Shell theme={null} gigalixir drains ``` </CodeGroup> You can remove any log drain you wish using the below command: <CodeGroup> ```shell Shell theme={null} gigalixir drains:remove LOG_DRAIN_ID ``` </CodeGroup> *Replace LOG\_DRAIN\_ID the log drain ID you are trying to remove.* ## Add new log drain Use the command below to create a new AppSignal log drain <CodeGroup> ```shell Shell theme={null} gigalixir drains:add "https://appsignal-endpoint.net/gigalixir?api_key=YOUR_LOG_SOURCE_API_KEY" ``` </CodeGroup> Replace `YOUR_LOG_SOURCE_API_KEY` with the key provided when creating a log source. When connected, logs should appear in AppSignal. If you still cannot see any logs, please [contact us](mailto:support@appsignal.com) for support. # Heroku Logs Source: https://docs.appsignal.com/logging/platforms/heroku <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> ## Cedar (Legacy Platform) applications ### Remove old log drains <Tip> This Heroku log drain setup will send both logs and metrics to AppSignal. To send only metrics to AppSignal, follow the Heroku log drain setup [in our Heroku documentation](/heroku/setup) instead. </Tip> Before creating a new log drain for AppSignal, you need to remove any pre-existing AppSignal log drains. You can check for any existing active log drains using the command below, where `myapp` is the name of your Heroku application: <CodeGroup> ```shell Shell theme={null} heroku drains -a myapp ``` </CodeGroup> If there are any active AppSignal log drains, you can remove them using the following command: <CodeGroup> ```shell Shell theme={null} heroku drains:remove -a myapp <url> ``` </CodeGroup> *Replace `<url>` above with the URL of the log drain you are trying to remove* ### Add new log drain Once any active log drains have been removed, [follow the instructions to create a Heroku log source](/logging/configuration#creating-a-log-source). Once you have created a log source, use the command below to create a new log drain. <CodeGroup> ```shell Shell theme={null} heroku drains:add "https://appsignal-endpoint.net/logplex?api_key=YOUR_LOG_SOURCE_API_KEY" ``` </CodeGroup> Replace `YOUR_LOG_SOURCE_API_KEY` with the key provided when creating a log source. When connected, logs should appear in AppSignal. If you still cannot see any logs, please [contact us](mailto:support@appsignal.com) for support. ### Severity parsing By default, Heroku sends all logs with an INFO severity. And since the content of logdrain messages can depend on the source (add-ons, application, Heroku router etc.), there are a couple of ways to override the default severity. #### Log format Set a log format and override the severity. You can set the format of your log lines in the source to "logfmt" and emit the following string in your logline `severity=warning`. This will override the default `INFO` severity to `WARNING`. #### Severity parsing When adding a Heroku log source in AppSignal, there's a checkbox to enable "Severity parsing." When checked, we will attempt to parse any valid severity string from the log message. We only do this when the alternatives have not yielded any results (e.g., if you set the source log format to logfmt and emit a severity attribute, that is used instead of the parsed severity). The following strings are considered valid severities; they can be uppercase, lowercase, or mixed case: * TRACE * DEBUG * INFO * NOTICE * WARNING * WARN * ERR * ERROR * CRIT * CRITICAL * ALERT * EMERG * PANIC * FATAL We will not consider these strings a severity, if they are part of a word. Severities encased in blocks are considered severities, for example: These are parsed as severities: ```shell Shell theme={null} [oban] [error] invalid query ERROR - My app is broken error something went wrong [Error] this is a valid error severity ``` *Note that this means any lowercase severity string (info/debug/warning/trace/etc) anywhere in the log line will change the log severity.* These are not parsed as severities: ```shell Shell theme={null} ErrorClass error: something went wrong The doctor was panicking just as much as the patient ``` ## Fir applications To send logs from your Heroku Fir application to AppSignal, follow the [setup steps for Heroku Fir generation applications](/heroku/setup#fir-applications). AppSignal will automatically ingest logs from your application through OpenTelemetry HTTP exporters, or any logs from `stdout` and `stderr` via a [Heroku Telemetry Drain](https://devcenter.heroku.com/articles/log-drains). # Netlify Source: https://docs.appsignal.com/logging/platforms/netlify You can configure Netlify to send logs to a dedicated endpoint. Currently, Netlify only supports the exporting of function logs. To configure Netlify to send function logs to AppSignal, follow the steps outlined below: 1. Under **Site settings > Log Drains**, select "**Enable a log drain**". 2. Select "**General HTTP endpoint**" as the Log drain service. 3. Select only "**function logs**" as the **Log type**. 4. Enter the following URL for your endpoint: <CodeGroup> ```shell Shell theme={null} https://appsignal-endpoint.net/logs/netlify?api_key=YOUR_LOG_SOURCE_API_KEY ``` </CodeGroup> Replace `YOUR_LOG_SOURCE_API_KEY` with the key provided when [creating a log source](/logging/configuration#creating-a-log-source). 1. Select [`NDJSON`](/logging/formatting#ndjson) as the **Log Drain Format**. 2. Once you've completed the steps above, select "**Connect**". When connected, logs should appear in AppSignal. If you still cannot see any logs, please [contact us](mailto:support@appsignal.com) for support. You can find more information on Netlify's log drains in their [Log Drain](https://docs.netlify.com/monitor-sites/log-drains/#general-http-endpoint) documentation. # Render Logs Source: https://docs.appsignal.com/logging/platforms/render <Tip> Please note that when running multiple applications on Render, AppSignal will receive logs for all your applications and currently cannot automatically filter them. To avoid sending unnecessary logs, we recommend sending logs via [AppSignal for Ruby, Elixir, or Node](/logging/integrations) when running multiple apps on Render. </Tip> You can configure a Log Stream with Render to send logs to AppSignal. Render logs will be in the [Syslog RFC 5424](/logging/formatting) format. To configure Render to send logs to AppSignal, follow the steps outlined below: 1. To open Render's Create Log Stream form, navigate to **Account/Team settings > Log Streams**, and select "**Add Log Stream**". 2. Enter the following URL in the Log Endpoint field: <CodeGroup> ```shell Shell theme={null} appsignal-endpoint.net:6514 ``` </CodeGroup> 1. In the Token field, add the key provided when [creating a log source](/logging/configuration#creating-a-log-source). 2. Once you've completed the steps above, select "**Create Log Stream**". When connected, Render logs should appear in AppSignal. If you still cannot see any logs, please [contact us](mailto:support@appsignal.com) for support. You can find more information on Render's Log Streams in their [Log Streams](https://render.com/docs/log-streams) documentation. # Scalingo Log Drain Source: https://docs.appsignal.com/logging/platforms/scalingo <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> AppSignal can automatically ingest logs via [Scalingo Log Drain](https://doc.scalingo.com/platform/app/log-drain#appsignal). Scalingo log drains can be managed using Scalingo's [CLI](https://doc.scalingo.com/platform/cli/start). ## Check For Existing Log Drains Before creating a new log drain for AppSignal, we recommend checking to see if a drain for AppSignal already exists. You can do so using the following command: <CodeGroup> ```shell Shell theme={null} scalingo --app my-app log-drains ``` </CodeGroup> You can remove any log drain you wish using the below command: <CodeGroup> ```shell Shell theme={null} scalingo --app my-app log-drains-remove LOG_DRAIN_URL ``` </CodeGroup> *Replace LOG\_DRAIN\_URL with the log drain URL you are trying to remove.* ## Add New Log Drain Use the command below to create a new AppSignal log drain: <CodeGroup> ```shell Shell theme={null} scalingo --app my-app log-drains-add --type appsignal --token YOUR_LOG_SOURCE_API_KEY ``` </CodeGroup> Replace `YOUR_LOG_SOURCE_API_KEY` with the key provided when creating a log source. When connected, logs should appear in AppSignal. If you still cannot see any logs, please [contact us](mailto:support@appsignal.com) for support. # Vector Source: https://docs.appsignal.com/logging/platforms/vector <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> AppSignal can ingest logs via your Vector instance. To send data from your Vector sources to AppSignal, you need to set up the AppSignal Vector sink in your Vector configuration and create a new Vector logging source. You can read more about AppSignal's Vector integration in our [Vector documentation](/vector). ## Configure Sink To do this, create a new Vector sink with the type `appsignal`. You can define your logging sources via the `inputs` attribute in this sink. To successfully send logging data to AppSignal, you must also provide your [app-level Push API Key](https://appsignal.com/redirect-to/app?to=api_keys\&key_tab=app) via the `push_api_key` attribute: <CodeGroup> ```toml TOML theme={null} # vector.toml example # Other config here # Add this AppSignal sink section [sinks.appsignal] type = "appsignal" inputs = [ "internal_logs", "your_log_source" ] push_api_key = "YOUR_APP_LEVEL_API_KEY" ``` </CodeGroup> ## Create Logging Source Once your Vector Sink is configured, create a new [logging source](/logging/configuration#creating-a-log-source) and select Vector as the platform. Once created, AppSignal Logging will begin to display the configured logs. If you cannot see any logs, please [contact us](mailto:support@appsignal.com) for support. # Log Query Syntax Source: https://docs.appsignal.com/logging/query-syntax <Tip> This page describes our newest query syntax. For the syntax using `attributes`, see our [legacy query syntax](/logging/legacy-query-syntax) </Tip> AppSignal's log filtering system allows you to search and filter through your application logs using an intuitive query syntax. Whether you need to find specific error messages, filter by severity levels, or search through custom attributes, our query language makes it easy to pinpoint exactly what you're looking for. <img alt="Screenshot of expanded log" /> ## Quick Start Get started with these simple queries: <CodeGroup> ```sql SQL theme={null} timeout ``` </CodeGroup> Searches for "timeout" in the message field. <CodeGroup> ```sql SQL theme={null} severity=error ``` </CodeGroup> Finds all error-level logs. <CodeGroup> ```sql SQL theme={null} severity=error hostname=production-web-1 ``` </CodeGroup> Finds errors from a specific server. ## Available Fields You can query the following fields in your logs: | Field | Description | Example | | ----------------- | ---------------------------------------------- | ------------------------- | | `severity` | Log level (error, warning, info, debug, trace) | `severity=error` | | `hostname` | Application host | `hostname=production-1` | | `group` | Namespace defined for your application | `group="background jobs"` | | `message` | Log message content | `message:timeout` | | Custom attributes | Any custom attribute defined in your logs | `duration>10.1` | If no field is provided, the query will search the message field. ## Query Operators ### Search Operators | Operator | Syntax | Description | Example | | -------- | -------------- | ---------------------- | ----------------- | | `:` | `field:value` | Contains value | `message:error` | | `!:` | `field!:value` | Does not contain value | `hostname!:test` | | `=` | `field=value` | Exact match | `severity=error` | | `!=` | `field!=value` | Not equal to | `source!=mongodb` | Use quotes for values with spaces: `group:"background jobs"` ### Comparison Operators For numeric values: | Operator | Syntax | Description | Example | | -------- | ------------------ | ------------------------ | --------------- | | `>` | `attribute>value` | Greater than | `duration>100` | | `<` | `attribute<value` | Less than | `user_id<1000` | | `>=` | `attribute>=value` | Greater than or equal to | `duration>=100` | | `<=` | `attribute<=value` | Less than or equal to | `user_id<=1000` | ### Nested Attributes We'll use the following example JSON structure: <CodeGroup> ```json JSON theme={null} { "message": "User logged in", "group": "admin", "hostname": "production-1", "user": { "id": 123, "name": "John Doe", "emails": ["john@example.com", "john@work.com"], "location.country": "US" } } ``` </CodeGroup> Query nested JSON attributes using dot notation: <CodeGroup> ```sql SQL theme={null} user.id=123 ``` </CodeGroup> Access nested object properties. <CodeGroup> ```sql SQL theme={null} user.emails.0=john@example.com ``` </CodeGroup> Query array elements by index (zero-based). <CodeGroup> ```sql SQL theme={null} user.location\.country=US ``` </CodeGroup> Escape dots that are part of the field name itself using a backslash. ## Combining Queries ### AND Logic (Default) Space-separated queries are combined with AND: <CodeGroup> ```sql SQL theme={null} severity=error hostname=production-1 ``` </CodeGroup> Finds errors from production-1. ### OR Logic Use `OR` to match any condition: <CodeGroup> ```sql SQL theme={null} severity=error OR severity=warning ``` </CodeGroup> Finds errors or warnings. ### Grouping with Parentheses Use parentheses for complex queries: <CodeGroup> ```sql SQL theme={null} severity=error AND (hostname=web-1 OR hostname=web-2) ``` </CodeGroup> Finds errors from either web-1 or web-2. # Triggers Source: https://docs.appsignal.com/logging/triggers This documentation explains how to create triggers to alert you of specific logging behaviors. You can read our [Anomaly Detection documentation](/anomaly-detection) for more information on AppSignal's alerting functionality. ## Creating Triggers To create a new trigger, navigate to [Triggers](https://appsignal.com/redirect-to/app?to=logging/triggers) in the Logging Navigation, and click "Create a log trigger". You will then be requested to define the following trigger attributes: * [Name and Description](#name-trigger) * [Trigger Query](#trigger-query) * [Threshold](#threshold) * [Severity](#severity) * [Source](#source) * [Notifier](#notifier) ### Name & Description In the *Create new trigger* form, give your trigger a functional name and description, for example, "Slow Process Trigger". ### Trigger Query Logging triggers are query based, meaning an alert is triggered when the conditions of a logging query are met. For example, if we have a logging attribute called `duration` that records how long an API request takes to complete, and we want to be alerted when that attribute is greater than 50, we would create a trigger with the following query: ```bash Shell theme={null} attributes.duration > 50 ``` You can read more about AppSignal's query syntax in our [query syntax documentation](/logging/query-syntax). ### Threshold You can define a threshold for your trigger to ensure you only receive alerts when necessary. Logging triggers can have the following thresholds: * Every Occurrence * First After Close * Nth in an hour * Nth in a day If you want to prevent a trigger from notifying you, you can select "Never Notify". The Never Notify threshold is mainly used for benign issues you want to keep track of but are not urgent enough to justify triggering an alert. You can read more about thresholds in our [Notification Settings documentation](/application/notification-settings#notification-options). ### Set Trigger Severity Triggers can be scoped to the following severities: * Critical * High * Low * Info If we select the Critical severity, our trigger will only be triggered when a critical severity log matches our query. If you do not wish to scope your trigger on severity, you can choose **"Not set"**, meaning the trigger will be triggered when its query is matched for any log severity. ### Trigger Source Define which logging sources your query applies to. ### Trigger Notifier Define how you are notified once a trigger is triggered, for example, via email or Slack. Logging currently supports the following notifiers: * Discord * Email * Google Hangouts * Opsgenie * Pagerduty * Slack * MS Teams * Webhook You can read more about integrating AppSignal with notifiers in our [Integrations documentation](/application/integrations#available-notifiers). ### Save & Manage Triggers Once saved, if the conditions of your trigger are met, you will be alerted via your preferred notifier platform. You can manage your logging triggers from the Triggers page. If you are struggling with integrating a notifier or are not receiving alerts, you can [reach out to us support](mailto:support@appsignal.com), we're here to help! # Troubleshooting Source: https://docs.appsignal.com/logging/troubleshooting If you're having trouble with RSyslog you may wish to follow some of the troubleshooting information in this documentation. Alternatively, you can review the official [RSyslog Troubleshooting Documentation](https://docs.rsyslog.com/doc/troubleshooting/index.html). If that still doesn't solve your problems, you can [contact us](mailto:support@appsignal.com), and we'll help you figure things out! ### Check Installation To see if the RSyslog daemon is installed, you can run the following terminal command: <CodeGroup> ```sh Shell theme={null} command -v rsyslogd ``` </CodeGroup> If RSyslog is installed, the output of this command will be the path to the RSyslog binary. If nothing is returned by this command, rsyslog is probably not installed. For installation instructions, please refer to the official [RSyslog Installation Documentation](https://www.rsyslog.com/doc/master/installation.html). To see if the RSyslog daemon is running, you can run the following terminal command: <CodeGroup> ```sh Shell theme={null} pgrep rsyslogd ``` </CodeGroup> If RSyslog is running, the output of this command will be the process ID of the currently running RSyslog daemon process. If nothing is returned by this command, the RSyslog daemon is not running. In most RSyslog installations, the following command will start the RSyslog daemon: <CodeGroup> ```sh Shell theme={null} systemctl start rsyslog ``` </CodeGroup> ### Debugging If you run into issues, you may wish to inspect the behaviour of the RSyslog daemon. To do so, you can configure RSyslog to create a debug log. Add the following lines at the beginning of your `rsyslog.conf` file: ```text Text theme={null} $DebugFile /tmp/rsyslogd.log $DebugLevel 2 ``` A `DebugLevel` of `2` activates always-on debug mode, while a level of `0` turns debug mode off. For other debugging options, please refer to the [RSyslog Debug Log Documentation](https://www.rsyslog.com/doc/v8-stable/troubleshooting/howtodebug.html#how-to-create-a-debug-log). To apply the configuration changes, restart the RSyslog daemon process: <CodeGroup> ```sh Shell theme={null} systemctl restart rsyslog ``` </CodeGroup> You can now review the RSyslog debug logs at `/tmp/rsyslogd.log`. When you're done, make sure to deactivate debug mode by undoing the configuration changes and restarting RSyslog again. <Note> πŸ”Ž For further information on troubleshooting and debugging with syslog please refer to the official [RSyslog Troubleshooting Documentation](https://www.rsyslog.com/doc/v8-stable/troubleshooting/). </Note> # Wrap process monitoring Source: https://docs.appsignal.com/logging/wrap-process-monitoring ## Logging By default, `appsignal-wrap` will send both the standard output and standard error of the process it monitors as logs to AppSignal. The logs will appear under the "application" source, and the name provided as the first argument will be used as the log group. ### Disable logging To disable sending either the standard output or standard error as logs, you can use the `--no-stdout` or `--no-stderr` command-line options respectively. To disable sending logs altogether, you can use the `--no-log` command-line option. ### Custom log group To send logs as a different log group, you can pass it as an argument to the `--log` command-line option. For example: <CodeGroup> ```sh Shell theme={null} appsignal-wrap mysql --log db -- mysqld ``` </CodeGroup> In the above example, `appsignal-wrap` will use `db` as the log group when sending logs to AppSignal, but will still use `mysql` as the name to identify the process when reporting process monitors and errors. ### Custom log source To send logs to a different log source, you can pass the log source's API key, which you obtain when [creating a log source](https://docs.appsignal.com/logging/configuration.html#creating-a-log-source), as an argument to the `--log-source` command-line option, or as the `APPSIGNAL_LOG_SOURCE_API_KEY` environment variable. For example: <CodeGroup> ```sh Shell theme={null} export APPSIGNAL_LOG_SOURCE_API_KEY=[LOG_SOURCE_API_KEY] appsignal-wrap mysql -- mysqld ``` </CodeGroup> # AppSignal MCP Source: https://docs.appsignal.com/mcp-server <Tip> AppSignal MCP is currently in preview. Join our <a href="https://discord.gg/fT2cbMuQSJ">Discord community</a> to help test and shape this implementation. </Tip> [Model Context Protocol (MCP)][mcp] enables AI agents and AI code editors like Claude, Cursor, Windsurf, Zed, VS Code, and GitHub Copilot to interact with external tools and data sources. AppSignal MCP gives those agents direct access to your monitoring data: errors, traces, logs, metrics, and more. AppSignal MCP is a public HTTP endpoint at `https://appsignal.com/api/mcp`. Most agents connect to it directly. If you'd rather run a local proxy β€” for example, in an environment that restricts outbound traffic β€” an [optional Docker image][github-repo] is available. ## What you can access AppSignal MCP exposes read and write access to your monitoring data across seven areas. Each area maps to a permission you can configure when authenticating: with an MCP token, set each area to `read`, `write`, or disabled; with OAuth, all read and write tools are exposed at once. What you get back depends on what your apps send to AppSignal. If your app is not sending logs, `get_log_lines` will not return anything. AppSignal MCP is a gateway to data AppSignal already has. It does not collect new data on its own. ### Available now * **Error incidents** (read + write): list and search exceptions, inspect stack traces, update state and severity, assign handlers, and add notes * **Performance** (read): rank slowest actions, pull traces, walk span trees, and inspect span attributes. Sample-based for standard Ruby and Elixir apps; OpenTelemetry traces for apps sending OTel data * **Anomaly detection** (read + write): browse alerts, list existing triggers, and create, update, or archive triggers * **Logging** (read + write): query log lines with AppSignal's expression syntax, and set up log ingestion rules: filter, trigger, and metrics actions. Particularly powerful for stitching together a customer journey across log sources, errors, and traces in one prompt β€” see [reconstructing a customer journey](/mcp/reference#reconstructing-a-customer-journey) * **Metrics** (read): discover metric categories (including `host_metrics`), list metric names and tags, and pull timeseries or aggregated values * **Dashboards** (read + write): create dashboards, and add or update chart visuals * **App discovery** (read): list your applications, environments, namespaces, users, notifiers, log sources, log line actions, and deploy markers For the full list of tools, parameters, and example prompts, see the [MCP Tool Reference](/mcp/reference). ### Outside the toolset's scope A few AppSignal features are intentionally not exposed through dedicated MCP tools. In most cases there's already a better way to access the data, or a natural-language interface isn't the right fit for the job. Every tool exposed also takes up space in your agent's context, so we'd rather keep the toolset focused than mirror every part of the app. * **Uptime monitor management**: uptime results are stored as metrics (`uptime_monitor_error_count` and `uptime_monitor_duration`), so you can already query them through the existing metrics tools (`get_metric_names`, `get_metric_tags`, `get_metrics_timeseries`, and `get_metrics_list`). Dedicated tools for listing or creating uptime monitors are not on the roadmap at the moment. * **Notifier, user, and deploy marker management**: creating or modifying these requires owner-level permissions and has real consequences: a misinterpreted prompt could grant the wrong person access or misroute alerts. Admin operations like these are better handled in the AppSignal UI, where they're explicit and easy to audit. You can still read notifiers, users, and deploy markers through `get_app_resources`. * **Custom metric and signal ingestion**: AppSignal's ingest path runs on dedicated endpoints optimized for high-throughput delivery, and AppSignal MCP is not designed for pushing data. To send [custom metrics](/metrics/custom), use the AppSignal integration in your application. ### On the roadmap if there's demand * **Process monitor querying**: read access to cron and heartbeat process monitor data. We'd like to gauge interest before adding this. These are current stances and can change as the way agents work evolves. If you hit a wall with the current toolset, let us know in the [Discord community](https://discord.com/channels/1361347709839085671/1387797163513348146) so we can weigh it against the list. ## Authentication You need an [AppSignal account][appsignal-sign-up] to get started. AppSignal MCP supports two authentication methods β€” pick whichever fits the AI agent you're configuring: * **OAuth** β€” sign in with your AppSignal account once. Access is granted at the application level and exposes all read and write tools at once. The recommended path for GitHub Copilot CLI, and the simplest setup for editors that natively support remote MCP servers (Claude Code, VS Code) or that can run [`mcp-remote`][mcp-remote] as a bridge (Cursor, Windsurf, Zed). * **Bearer token** β€” generate a long-lived [MCP token][appsignal-mcp-token] with fine-grained permissions per toolset. Each token can be set to `read`, `write`, or disabled per area, scoped to specific applications, and configured to automatically expose new tools as they ship. Best when you want to limit what an agent can do. If you're getting started and your agent supports OAuth, that's the quicker path. If you need per-tool permissions or per-app scoping, generate an MCP token instead. To generate a Bearer token: 1. Select your profile icon. 2. Go to **Account Settings**. 3. Select **MCP Tokens** to create a new token. ## Configuration Configure AppSignal MCP in your AI agent's settings using the HTTP endpoint `https://appsignal.com/api/mcp`. Each section below has tabs for OAuth and Bearer token β€” pick whichever you set up above. <Tip> OAuth support is new across our supported editors. If the OAuth tab errors out for your editor, fall back to the Bearer token tab and let us know in our <a href="https://discord.gg/fT2cbMuQSJ">Discord community</a> so we can tighten these instructions. </Tip> ### Claude Code <CodeGroup> ```bash OAuth theme={null} claude mcp add --transport http appsignal https://appsignal.com/api/mcp ``` ```bash Bearer token theme={null} claude mcp add --transport http appsignal https://appsignal.com/api/mcp \ --header "Authorization: Bearer your-mcp-token" ``` </CodeGroup> With OAuth, Claude Code starts the browser-based sign-in flow the first time AppSignal tools are invoked. See the [Claude Code MCP docs][claude-code-mcp] for transport flags and CLI reference. ### Cursor Edit `~/.cursor/mcp.json`: <CodeGroup> ```json OAuth theme={null} { "mcpServers": { "appsignal": { "command": "npx", "args": ["-y", "mcp-remote", "https://appsignal.com/api/mcp"] } } } ``` ```json Bearer token theme={null} { "mcpServers": { "appsignal": { "url": "https://appsignal.com/api/mcp", "headers": { "Authorization": "Bearer your-mcp-token" } } } } ``` </CodeGroup> The OAuth setup uses [`mcp-remote`][mcp-remote] as a local bridge to the HTTP endpoint. The browser-based sign-in flow opens the first time Cursor connects. See the [Cursor MCP docs][cursor-mcp] for the full schema. ### Windsurf Edit `~/.codeium/windsurf/mcp_config.json`: <CodeGroup> ```json OAuth theme={null} { "mcpServers": { "appsignal": { "command": "npx", "args": ["-y", "mcp-remote", "https://appsignal.com/api/mcp"] } } } ``` ```json Bearer token theme={null} { "mcpServers": { "appsignal": { "serverUrl": "https://appsignal.com/api/mcp", "headers": { "Authorization": "Bearer your-mcp-token" } } } } ``` </CodeGroup> See the [Windsurf MCP docs][windsurf-mcp] for the full schema and OAuth notes. ### Zed Open your Zed settings file and add the `context_servers` section: <CodeGroup> ```json OAuth theme={null} { "context_servers": { "appsignal": { "settings": {}, "enabled": true, "url": "https://appsignal.com/api/mcp" } } } ``` ```json Bearer token theme={null} { "context_servers": { "appsignal": { "settings": {}, "enabled": true, "url": "https://appsignal.com/api/mcp", "headers": { "Authorization": "Bearer your-mcp-token" } } } } ``` </CodeGroup> When the `Authorization` header is omitted, Zed initiates the standard MCP OAuth flow against AppSignal. See the [Zed MCP docs][zed-mcp] for the full `context_servers` schema. ### VS Code If you are running GitHub Copilot and are signed in under a company account, make sure to set "MCP servers in Copilot" to "Enabled" under your organization settings > Copilot > Policies. <img alt="GitHub Copilot settings" /> Add this to your `.vscode/mcp.json`: <CodeGroup> ```json OAuth theme={null} { "servers": { "appsignal": { "type": "http", "url": "https://appsignal.com/api/mcp" } } } ``` ```json Bearer token theme={null} { "inputs": [ { "type": "promptString", "id": "appsignal_mcp_token", "description": "AppSignal MCP Token", "password": true } ], "servers": { "appsignal": { "type": "http", "url": "https://appsignal.com/api/mcp", "headers": { "Authorization": "Bearer ${input:appsignal_mcp_token}" } } } } ``` </CodeGroup> With OAuth, VS Code initiates the sign-in flow the first time AppSignal tools are used. See the [VS Code MCP docs][vscode-mcp] for input variables and headers. ### GitHub Copilot CLI The GitHub Copilot CLI uses OAuth for MCP authentication. Run the following to add AppSignal: ```bash Bash theme={null} copilot mcp add appsignal https://appsignal.com/api/mcp ``` Follow the OAuth prompt to authorize AppSignal. Once connected, AppSignal tools will be available in Copilot CLI sessions. See the [GitHub Copilot CLI MCP docs][copilot-cli-mcp] for the interactive `/mcp add` flow and config file location. ## Getting Help We encourage you to join our [Discord community][discord] where you can: * Get help with AppSignal MCP setup * Share feedback and suggestions * Connect with other developers using AppSignal MCP * Stay updated on new features and improvements Look for the dedicated `#mcp` channel where our team actively monitors and responds to questions. [appsignal]: https://www.appsignal.com [appsignal-sign-up]: https://appsignal.com/users/sign_up [appsignal-mcp-token]: https://appsignal.com/users/mcp_tokens [discord]: https://discord.gg/fT2cbMuQSJ [github-repo]: https://github.com/appsignal/appsignal-mcp [mcp]: https://modelcontextprotocol.io/introduction [mcp-remote]: https://www.npmjs.com/package/mcp-remote [claude-code-mcp]: https://code.claude.com/docs/en/mcp [cursor-mcp]: https://cursor.com/docs/mcp [windsurf-mcp]: https://docs.windsurf.com/windsurf/cascade/mcp [zed-mcp]: https://zed.dev/docs/ai/mcp [vscode-mcp]: https://code.visualstudio.com/docs/copilot/chat/mcp-servers [copilot-cli-mcp]: https://docs.github.com/en/copilot/how-tos/copilot-cli/customize-copilot/add-mcp-servers # Big number visuals via MCP Source: https://docs.appsignal.com/mcp/big-number-visuals A Big Number is a single-value KPI chart, which is useful for showing a total, the latest reading, or an aggregated metric at a glance (e.g. total errors, current queue depth, mean request latency). This page covers how to use that feature from an AI agent connected to [AppSignal MCP](/mcp-server). For a tour of all dashboard chart types in the UI, see [Dashboards](/metrics/dashboards). ## What you can do With the `dashboards` permission set to `write`, an agent can: * Create a new dashboard to hold the chart (`manage_dashboard`) * Add a Big Number chart to any dashboard (`create_dashboard_visual` with `type: "number"`) * Change the metric, aggregate, or formatting on an existing chart (`update_dashboard_visual`) The chart renders the same way as one built in the AppSignal app, MCP is just another way to author it. <img alt="Big Number chart on a dashboard" /> ## Example prompt ```text Text theme={null} Add a Big Number chart to the "API Health" dashboard showing the mean of request_latency_ms over the selected time range, formatted as a duration. ``` The agent will translate that into a `create_dashboard_visual` call with: * `type: "number"` * `metric.name: "request_latency_ms"` * `metric.field: "mean"` * `metric.aggregate: "avg"` * `format: "duration"` ## Configuring the chart A Big Number chart needs one metric and one aggregation across the selected time range: * **Metric** β€” The metric name to be shown in this chart. You can either use the full metric name to select one metric, or use a wildcard (\_) to select multiple metrics at once: `db_users_document_count`, `db\__\_size`. See [metric naming](/metrics/custom#metric-naming) for the full rules. * **Aggregation type** β€” The aggregation used to display the metric value. The number on the chart is selected or calculated based on this aggregation, applied to the metric data reported in the selected time frame on the dashboard or preview: * `Maximum value` β€” the highest metric value * `Minimum value` β€” the lowest metric value * `Average value` β€” the average of the metric values * `Total value` β€” the combined value of the metric values * `First value` β€” the first metric value * `Last value` β€” the last metric value * **Data format** β€” Select the value format that is used to display values in the chart and chart legends. See [value formatting](/metrics/custom#metric-values-value-formatting) for the available formats. * **Tags** *(optional)* β€” Select which tags of the metric should be displayed in the chart: * When empty, all variations of a tag will create their own line in the chart. * Enter tags to filter for certain tag values. In this case, all tags of the metric need to be specified, either with a value or a wildcard. See [metric tags](/metrics/custom#metric-tags) for the full reference. <img alt="Big Number chart setup in the AppSignal UI" /> ## Sending the data MCP authors the visual; it does not ingest metrics. The metric you point a chart at must already be flowing into AppSignal via your integration. See [custom metrics](/metrics/custom) for how to send them from your application. # MCP Tool Reference Source: https://docs.appsignal.com/mcp/reference AppSignal MCP exposes 24 tools across seven areas: **error incidents**, **performance**, **anomaly detection**, **logging**, **metrics**, **dashboards**, and **app discovery**. Tools include both read and write operations. ## Workflows These examples show how tools compose together for common tasks. ### Investigating a production error 1. List recent open exceptions: *"Show me all open incidents in production from the last 24 hours"* 2. Get full details on a specific incident: *"Get the details for incident #847 including the stack trace"* 3. Pull traces to see what happened at the code level: *"Get the error traces for incident #847"* 4. Document your findings: *"Add a note to incident #847: investigated the database timeout β€” connection pool was exhausted during peak traffic"* 5. Resolve it: *"Close incident #847"* ### Profiling a slow action 1. Get a performance overview: *"Which actions are slowest in the web namespace right now?"* 2. Pull traces for the worst offender: *"Get traces for BlogPostsController#index from the last hour"* 3. Inspect the span tree to find the bottleneck: *"Show me the full span tree for trace abc123"* 4. Drill into a specific span: *"Get the details for span def456 in trace abc123"* ### Triaging a batch of incidents 1. *"Find all open incidents in the background namespace from the last week"* 2. *"Mark incidents #120, #121, and #122 as work in progress and assign them to Jana"* 3. *"Close all incidents related to ActionMailer β€” they were fixed in the last deploy"* ### Searching logs during an incident 1. *"Find all error logs from the last hour"* 2. *"Show me logs where message contains 'timeout' on web-1 between 14:00 and 15:00"* 3. *"Get fatal logs from the payments source over the last 30 minutes"* ### Reconstructing a customer journey When a user reports something went wrong, the answer is usually scattered across logs from multiple sources, plus errors and traces. Stitching that timeline together by hand is the kind of work the logging UI can't do for you, but an agent can. 1. *"Get all logs for user.id=4321 from production over the last 24 hours, across every source"* 2. *"Narrow that to the window between 14:00 and 15:30 UTC and group the results by source"* 3. *"List any open exception incidents from production in that same window β€” anything tagged with user.id=4321?"* 4. *"For incident #903, pull the error traces and walk the span tree"* 5. *"Summarize what happened: which actions did this user hit, what failed, and where did the error originate?"* This pulls from `get_log_lines`, `get_exception_incidents`, and `get_traces` in a single conversation. The final summary step is where MCP earns its keep β€” the agent composes the narrative, not you. ### Setting up log processing AppSignal executes log line actions during ingestion, in the order you define. A common pattern is to emit a metric, create a trigger, then filter β€” this ensures AppSignal captures the signal before discarding the log line. 1. Check the existing log line actions and their order: use `get_app_resources` with `sections: ["log_line_actions"]` 2. *"Create a metrics action that counts log lines where severity is error as log.error\_count"* 3. *"Add a trigger action that fires an alert when severity is fatal"* 4. *"Add a filter to drop all health check log lines"* 5. *"Reorder those actions so the metrics action runs first, then the trigger, then the filter"* ### Creating an anomaly detection trigger 1. Discover available metrics: *"What metrics are available for my production app?"* 2. Check available tags: *"What tags are available for response\_time?"* 3. Create the trigger: *"Create a trigger that fires when mean response time exceeds 500ms for more than 5 minutes, and notify the Slack #alerts channel"* 4. Archive an old trigger once replaced: use `get_triggers` to find the ID first, then *"Archive the old response\_time trigger"* ### Building a monitoring dashboard 1. *"What metrics are available for my production app?"* 2. *"Create a dashboard called 'API Health' in production"* 3. *"Add a line chart of p95 response time by action to the API Health dashboard"* 4. *"Add an area chart of error rate broken down by namespace"* *** ## Tool reference Every tool takes `app_name` and `app_environment` to identify which application to target. Both are matched case-insensitively, so `MyApp/Production` and `myapp/production` resolve to the same application. ### App discovery #### `get_applications` Get all AppSignal applications the user has access to. Returns applications in `app_name/app_environment` format. Use this first to discover available applications before calling other tools. No parameters required. *** #### `get_app_resources` Discover available resources in an AppSignal application β€” namespaces, dashboards, users, notifiers, log sources, log line actions, and deploy markers. Particularly useful when setting up triggers, assigning incidents, or understanding the structure of an application. | Parameter | Required | Description | | ----------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `app_name` | yes | Name of the AppSignal application. | | `app_environment` | yes | Environment (e.g. `production`, `staging`). | | `sections` | no | Sections to retrieve: `users`, `notifiers`, `namespaces`, `dashboards`, `log_sources`, `log_line_actions`, `log_views`, `deploy_markers`. Returns all if not specified. | *** ### Error incidents #### `get_exception_incidents` List and search AppSignal exceptions and errors. Use this to get an overview of recent exceptions, search within a time period, find incidents by state, or check which incidents need attention. Returns 50 incidents per page. | Parameter | Required | Description | | ----------------- | -------- | -------------------------------------------------------------------------------------- | | `app_name` | yes | Name of the AppSignal application. | | `app_environment` | yes | Environment. | | `namespaces` | no | Comma-separated list of namespaces to filter by (e.g. `web,background`). | | `start` | no | Start of time range in ISO 8601 format. Defaults to the most recent deploy if omitted. | | `end` | no | End of time range in ISO 8601 format. Required if `start` is provided. | | `states` | no | Comma-separated states: `open`, `closed`, `wip`. Returns all states if not specified. | | `page` | no | Page number (1-based, defaults to 1). | *** #### `get_incident` Get detailed information about an AppSignal incident. Returns current state, assignment, first and last occurrence, error messages, stack traces, or anomaly alert details. Supports exception and anomaly incidents. | Parameter | Required | Description | | ----------------- | -------- | ------------------------------------------------------------------- | | `app_name` | yes | Name of the AppSignal application. | | `app_environment` | yes | Environment. | | `number` | yes | The numeric incident ID shown in AppSignal URLs and incident lists. | *** #### `update_incidents` Bulk update incidents for an AppSignal application. Use this to change incident state, update severity, or assign and unassign team members across multiple incidents at once. Use `get_app_resources` with `sections: ["users"]` to find user IDs for assignment. | Parameter | Required | Description | | ----------------- | -------- | ------------------------------------------------------------------- | | `app_name` | yes | Name of the AppSignal application. | | `app_environment` | yes | Environment. | | `incidents` | no | List of incident numbers to update (e.g. `[123, 456, 789]`). | | `state` | no | `open`, `closed`, or `wip` (work in progress). | | `severity` | no | `critical`, `high`, `low`, `none`, `informational`, or `untriaged`. | | `assign_users` | no | List of user IDs to assign as handlers. | | `unassign_users` | no | List of user IDs to remove from the incident. | *** #### `create_incident_note` Create a note on an AppSignal incident. Markdown is supported. Use this to add comments, status updates, investigation findings, or resolution steps. | Parameter | Required | Description | | ----------------- | -------- | ----------------------------------------------- | | `app_name` | yes | Name of the AppSignal application. | | `app_environment` | yes | Environment. | | `number` | yes | The numeric incident ID. | | `content` | yes | Note content. Markdown formatting is supported. | *** ### Performance #### `get_performance` Performance overview: sample-based performance incidents and slow actions from traces. For standard Ruby and Elixir apps, returns sample-based performance incidents. For apps that also send OpenTelemetry traces, additionally returns a ranked list of actions with mean duration, throughput, and error rate. Apps being migrated to OpenTelemetry may return both. Follow-up tools: use `get_incident` to inspect a specific performance incident, `get_traces` to pull sample traces for a slow action, and `update_incidents` to change state, severity, or assignees. | Parameter | Required | Description | | ----------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `app_name` | yes | Name of the AppSignal application. | | `app_environment` | yes | Environment. | | `namespaces` | no | Comma-separated namespaces. Applies to both performance incidents and OpenTelemetry actions. | | `start` | no | Start of time range in ISO 8601 format. Defaults to the most recent deploy for sample-based incidents, or 24 hours ago for OpenTelemetry actions. | | `end` | no | End of time range in ISO 8601 format. Required if `start` is provided. | | `states` | no | Comma-separated states: `open`, `closed`, `wip`. Applies to sample-based incidents only. | | `revision` | no | Scope to a specific deploy. Use `"last"` for the most recent deploy, or pass a revision hash. Ignored when `start`/`end` is provided. Use `get_app_resources(sections: ["deploy_markers"])` to list available revisions. | | `page` | no | Page number for sample-based incidents (1-based, defaults to 1). OpenTelemetry actions are returned as a complete ranked list. | *** #### `get_traces` Query performance and error traces, inspect span trees, and view span details. Supports two trace types: * **Performance traces** β€” identified by namespace and `action_name`. Use these to investigate slow requests. * **Error traces** β€” identified by digest. Get the digest from `get_incident` or `get_exception_incidents`, then use it here to see the actual error traces. Each trace type supports three modes: 1. **List mode** β€” find traces and get trace IDs. Provide namespace + `action_name`, or `digest`. 2. **Tree mode** β€” pass a `trace_id` to see all spans as a compact tree. 3. **Span detail mode** β€” pass `trace_id` and `span_id` for full span attributes, events, and resource info. The typical workflow is: list traces β†’ inspect a trace tree β†’ drill into a span. | Parameter | Required | Description | | ----------------- | ----------------- | ------------------------------------------------------------------------------------------------------------------ | | `app_name` | yes | Name of the AppSignal application. | | `app_environment` | yes | Environment. | | `namespace` | yes (performance) | The namespace to search in (e.g. `web`, `background`). Not needed for error traces. | | `action_name` | yes (performance) | The action name (e.g. `BlogPostsController#index`). Not needed for error traces. | | `digest` | yes (error) | The exception incident digest. Switches to error trace mode. Cannot be combined with `namespace` or `action_name`. | | `trace_id` | no | Switches to tree mode. Returns all spans for this trace. | | `span_id` | no | Switches to span detail mode. Requires `trace_id`. | | `start` | no | Start of time range in ISO 8601 format. Defaults to 24 hours ago. Performance traces only. | | `end` | no | End of time range in ISO 8601 format. Defaults to now. Performance traces only. | | `min_duration_ms` | no | Filter to traces slower than this threshold in milliseconds. List mode only. | | `limit` | no | Maximum number of traces to return (1–100, default 25). List mode only. | *** ### Anomaly detection #### `get_anomaly_incidents` List and search AppSignal anomaly detection alerts. Returns 50 alerts per page, including timestamps and values for each alert. | Parameter | Required | Description | | ----------------- | -------- | ------------------------------------------------------------------------------------------- | | `app_name` | yes | Name of the AppSignal application. | | `app_environment` | yes | Environment. | | `state` | no | `open`, `closed`, `warmup`, `cooldown`, or `archived`. Returns all states if not specified. | | `trigger_id` | no | Filter to incidents from a specific trigger. Use `get_triggers` to find trigger IDs. | | `page` | no | Page number (1-based, defaults to 1). | *** #### `get_triggers` List anomaly detection triggers for an AppSignal application. Returns active (non-archived) triggers with their complete configuration β€” conditions, notifiers, and dashboard links. Use this to find trigger IDs before calling `manage_trigger` or `archive_trigger`. | Parameter | Required | Description | | ----------------- | -------- | --------------------------------------------------------------- | | `app_name` | yes | Name of the AppSignal application. | | `app_environment` | yes | Environment. | | `metric_name` | no | Filter by metric name (e.g. `response_time`, `error_rate`). | | `kind` | no | Filter by trigger kind. | | `tags` | no | Filter by tags, e.g. `[{"key": "hostname", "value": "web-1"}]`. | | `page` | no | Page number (1-based, defaults to 1). | *** #### `manage_trigger` Create or update an anomaly detection trigger. Triggers are immutable. When you update a trigger, AppSignal archives the existing one (closing all its alerts and incidents) and creates a new one with a version chain reference. Provide all fields for both create and update operations. Use `get_metric_names` and `get_metric_tags` to discover available metrics and fields. Use `get_app_resources(sections: ["notifiers"])` to find notifier IDs. | Parameter | Required | Description | | --------------------- | -------- | ------------------------------------------------------------------------------------------------- | | `app_name` | yes | Name of the AppSignal application. | | `app_environment` | yes | Environment. | | `metric_name` | yes | The metric this trigger monitors. | | `kind` | yes | Trigger kind. Use `"Advanced"` for custom metrics. | | `field` | yes | Metric field to compare: `gauge`, `mean`, `p90`, `p95`, `counter`, or `count`. | | `condition_value` | yes | Threshold value (e.g. `500.0` for "response time > 500ms"). | | `comparison_operator` | yes | `<`, `>`, `<=`, `>=`, `==`, or `!=`. | | `warmup_duration` | yes | Minutes the condition must be met before an alert opens. Use `0` for immediate. | | `cooldown_duration` | yes | Minutes the condition must no longer be met before an alert closes. | | `id` | no | ID of an existing trigger to update. If provided, archives the old trigger and creates a new one. | | `notifier_ids` | no | Notifier IDs to send alerts to. | | `tags` | no | Tag filters to scope which metrics are included. Supports wildcards (`*`). | | `name` | no | Display name. Defaults to the metric name if not provided. | | `description` | no | Description of what this trigger monitors and what to do when it fires. | | `dashboard_id` | no | Dashboard ID to link in notifications. | | `no_match_is_zero` | no | If true, treat missing metric data as 0. Useful for counters that may not report when idle. | | `format` | no | Data format of the metric (e.g. `duration`, `size`, `percent`). | *** #### `archive_trigger` Archive an anomaly detection trigger and close all associated alerts and incidents. Idempotent β€” no-ops if the trigger is already archived. Use `get_triggers` to find the trigger ID. | Parameter | Required | Description | | ----------------- | -------- | ---------------------------------- | | `app_name` | yes | Name of the AppSignal application. | | `app_environment` | yes | Environment. | | `id` | yes | ID of the trigger to archive. | *** ### Logging #### `get_log_lines` Query log lines using AppSignal's expression syntax. Supports exact match, contains, negation, numeric comparisons, boolean logic, and nested attributes. Returns up to 100 lines per call, newest-first by default. For large time ranges, split into multiple calls and iterate forward. **Query syntax:** | Pattern | Example | | ------------------ | ------------------------------------------------------- | | Exact match | `severity=error` | | Contains | `message:timeout` | | Does not contain | `message!:debug` | | Not equal | `hostname!=web-1` | | Numeric comparison | `duration>100` | | Boolean logic | `severity=error AND (hostname=web-1 OR hostname=web-2)` | | Quoted values | `group="background jobs"` | | Nested attributes | `user.id=123` | Available fields: `severity`, `hostname`, `group`, `message`, and any custom attributes. | Parameter | Required | Description | | ----------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------- | | `app_name` | yes | Name of the AppSignal application. | | `app_environment` | yes | Environment. | | `query` | yes | Expression query. Use an empty string to retrieve all logs. | | `source_ids` | no | IDs of log sources to query. Queries all sources if not specified. Use `get_app_resources(sections: ["log_sources"])` to find source IDs. | | `start` | no | Start of time range in ISO 8601 format. Defaults to one query window ago. | | `end` | no | End of time range in ISO 8601 format. Defaults to now. | | `limit` | no | Number of log lines to return (1–100, default 50). | | `order` | no | `desc` (newest first, default) or `asc` (oldest first). | *** #### `manage_log_line_action` Create or update a log line action. Log line actions run during log ingestion, in the order you define. There are three types: * **filter** β€” discards matching log lines so they are never stored or processed further * **trigger** β€” fires alerts and incidents when the query matches * **metrics** β€” extracts counter, gauge, or distribution metrics from matching log lines Execution order matters: if a filter discards a log line, subsequent actions never see it. A common pattern is to place metric and trigger actions before any filter actions. Use `reorder_log_line_actions` to change the order after creation. New actions are appended at the end of the execution order. | Parameter | Required | Description | | ------------------ | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `app_name` | yes | Name of the AppSignal application. | | `app_environment` | yes | Environment. | | `name` | yes (create) | Name of the action (e.g. `"Drop health checks"`, `"Track error count"`). | | `query` | yes (create) | Query expression to match against log lines. | | `action_type` | yes (create) | `filter`, `trigger`, or `metrics`. Cannot be changed on update. | | `id` | no | ID of an existing action to update. If omitted, creates a new action. | | `source_ids` | no | Log source IDs this action applies to. Applies to all sources if not specified. | | `log_line_metrics` | no | Metric definitions to extract. Required when creating a `metrics` action. Each metric requires `name` and `metric_type` (`counter`, `gauge`, or `distribution`). `gauge` and `distribution` also require a `field` to extract the value from. When updating, replaces all existing metric definitions. | *** #### `reorder_log_line_actions` Change the execution order of log line actions. Provide action IDs in the desired sequence. Any action IDs not included are appended at the end in their current relative order. Use `get_app_resources(sections: ["log_line_actions"])` to find IDs and see the current order. | Parameter | Required | Description | | ----------------- | -------- | ------------------------------------------------------------------------------------------------- | | `app_name` | yes | Name of the AppSignal application. | | `app_environment` | yes | Environment. | | `action_ids` | yes | Ordered list of log line action IDs. The first ID in the list is executed first during ingestion. | *** #### `delete_log_line_action` Permanently delete a log line action. Use `get_app_resources(sections: ["log_line_actions"])` to find the action ID first. | Parameter | Required | Description | | ----------------- | -------- | ------------------------------------ | | `app_name` | yes | Name of the AppSignal application. | | `app_environment` | yes | Environment. | | `id` | yes | ID of the log line action to delete. | *** ### Metrics #### `discover_metrics` Discover available metric categories and their metrics for monitoring. Use this to get an overview of what you can monitor, or drill into a specific category. Also accepts a `dashboard:id` reference to show metrics used in a specific dashboard. | Parameter | Required | Description | | ----------------- | -------- | ------------------------------------------------------------------------------------------------ | | `app_name` | yes | Name of the AppSignal application. | | `app_environment` | yes | Environment. | | `metric_subject` | no | Metric category name (e.g. `performance_metrics`, `host_metrics`) or a `dashboard:id` reference. | *** #### `get_metric_names` Get the names of all metrics for the given application. Returns metric names as a comma-separated string. Use these as input to `get_metric_tags`, `get_metrics_timeseries`, and `get_metrics_list`. | Parameter | Required | Description | | ----------------- | -------- | ---------------------------------- | | `app_name` | yes | Name of the AppSignal application. | | `app_environment` | yes | Environment. | *** #### `get_metric_tags` Get the tags and metric type (Gauge, Counter, etc.) for a specific metric. Use the results to build valid queries with `get_metrics_timeseries` and `get_metrics_list`. | Parameter | Required | Description | | ----------------- | -------- | --------------------------------------------------------------------- | | `app_name` | yes | Name of the AppSignal application. | | `app_environment` | yes | Environment. | | `metric_name` | yes | Name of the metric. Use `get_metric_names` to find available metrics. | *** #### `get_metrics_timeseries` Get a timeseries for a metric in the given application. Returns point-by-point data for a given time range, metric type, and tag combination. Tag values support wildcard matching with `*`. | Parameter | Required | Description | | ----------------- | -------- | --------------------------------------------------------------------------------------------------- | | `app_name` | yes | Name of the AppSignal application. | | `app_environment` | yes | Environment. | | `metric_name` | yes | Name of the metric. | | `metric_type` | yes | `COUNT`, `COUNTER`, `GAUGE`, `MEAN`, `P90`, or `P95`. Use `get_metric_tags` to find the valid type. | | `start` | yes | Start of time range in ISO 8601 format. | | `end` | yes | End of time range in ISO 8601 format. | | `tags` | no | Tag filters, e.g. `[{"key": "hostname", "value": "web*"}]`. Supports `*` wildcards. | *** #### `get_metrics_list` Get an aggregated value for a metric over a time range. Returns a single aggregated value rather than a point-by-point timeseries. Useful for summary views. | Parameter | Required | Description | | ----------------- | -------- | ---------------------------------------------------------------- | | `app_name` | yes | Name of the AppSignal application. | | `app_environment` | yes | Environment. | | `metric_name` | yes | Name of the metric. | | `metric_type` | yes | `COUNT`, `COUNTER`, `GAUGE`, `MEAN`, `P90`, or `P95`. | | `start` | yes | Start of time range in ISO 8601 format. | | `end` | yes | End of time range in ISO 8601 format. | | `tags` | no | Tag filters, e.g. `[{"key": "hostname", "value": "frontend1"}]`. | *** ### Dashboards #### `manage_dashboard` Create or update an AppSignal dashboard. This tool manages dashboard metadata only (title and description). Use `create_dashboard_visual` and `update_dashboard_visual` to add charts. | Parameter | Required | Description | | ----------------- | -------- | -------------------------------------------------------------------------- | | `app_name` | yes | Name of the AppSignal application. | | `app_environment` | yes | Environment. | | `title` | yes | Dashboard title. | | `description` | no | Description of the dashboard's purpose and contents. | | `id` | no | Dashboard ID for updating an existing dashboard. Omit to create a new one. | *** #### `create_dashboard_visual` Add a new chart or graph to an existing dashboard. Use `discover_metrics` or `get_metrics_list` to find available metrics first. | Parameter | Required | Description | | ------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------ | | `app_name` | yes | Name of the AppSignal application. | | `app_environment` | yes | Environment. | | `dashboard_id` | yes | ID of the dashboard to add the visual to. | | `title` | yes | Chart title. | | `metrics` | yes | Array of metrics to display. Each requires `name`, `fields` (e.g. `mean`, `p90`, `p95`, `count`), and optionally `tags`. | | `description` | no | Additional context about the visual. | | `display` | no | `line` (default), `area`, or `area_relative`. | | `line_label` | no | Custom label for chart lines. Supports `%name%`, `%field%`, and `%tag%` replacements. | | `format` | no | Value format, e.g. `duration`, `size`, `percentage`. | | `draw_null_as_zero` | no | Whether to draw missing data points as zero. Default: `false`. | | `min_y_axis` | no | Minimum Y-axis value. | | `tags` | no | Global tags applied to all metrics in this visual. | *** #### `update_dashboard_visual` Update an existing chart or graph on a dashboard. All fields are optional except the identifiers. Unspecified fields keep their current values. If `metrics` is provided, it replaces all existing metrics on that visual. | Parameter | Required | Description | | ------------------- | -------- | ------------------------------------------------------------------------------------- | | `app_name` | yes | Name of the AppSignal application. | | `app_environment` | yes | Environment. | | `visual_id` | yes | ID of the visual component to update. | | `title` | no | New title. Current title is kept if not provided. | | `description` | no | New description. Set to an empty string to remove. | | `metrics` | no | Updated metrics array. Replaces all existing metrics if provided. | | `display` | no | `line`, `area`, or `area_relative`. | | `line_label` | no | Custom label for chart lines. Supports `%name%`, `%field%`, and `%tag%` replacements. | | `format` | no | Value format, e.g. `duration`, `size`, `percentage`. | | `draw_null_as_zero` | no | Whether to draw missing data points as zero. | | `min_y_axis` | no | Minimum Y-axis value. | | `tags` | no | Global tags. Replaces existing global tags if provided. | *** ## Token permissions Each MCP token has configurable permissions by toolset: `app`, `exceptions`, `performance`, `metrics`, `anomalies`, `dashboards`, `logging`. Each toolset can be set to `read`, `write`, or disabled. Tokens can also be scoped to specific applications and set to automatically expose new tools as they are added. To generate a token: 1. Select your profile icon. 2. Go to **Account Settings**. 3. Select **MCP Tokens** to create a new token. *** ## Missing a tool? <Tip> If your AI agent or editor can't accomplish something you'd expect to be possible, let it know. AppSignal MCP includes a built-in feedback mechanism that logs requests for capabilities that don't yet exist β€” this helps the AppSignal team prioritize what to build next. You can also post feature requests in the <a href="https://discord.gg/fT2cbMuQSJ">Discord community</a>. </Tip> # AWS magic dashboards Source: https://docs.appsignal.com/metrics/aws-dashboards AppSignal automatically creates magic dashboards for AWS services when it detects their metrics. Each AWS service gets its own dashboard with pre-built charts, so you get useful monitoring of your AWS infrastructure without building dashboards from scratch. These dashboards appear in **Dashboards** grouped under **AWS**, with a separate dashboard for each service (for example, `AWS/Lambda`, `AWS/RDS`, or `AWS/SQS`). The metrics that power them currently arrive through [CloudWatch Metric Streams](/metrics/cloudwatch-overview). ## How AWS dashboards are created When AppSignal receives metrics from an AWS service, it matches the metric names against its list of supported services. If there is a match, AppSignal creates a dashboard for that service in your app. Each chart uses wildcard tag filters to show all resources of a given type as separate lines. For example, the Lambda Errors chart shows a line for each function, tagged by `FunctionName`. You can narrow the view using the tag filters in the chart options. ## Setup To start receiving AWS metrics in AppSignal, set up a CloudWatch Metric Stream that sends data through Amazon Data Firehose to AppSignal's HTTP endpoint. There are two ways to do this: * [Console setup](/metrics/cloudwatch) β€” create each resource manually in the AWS Console. * [CloudFormation](/metrics/cloudwatch-cloudformation) β€” deploy a single template that creates all required resources in one step. See the [AWS CloudWatch metrics overview](/metrics/cloudwatch-overview) for details on metric naming, tags, filtering, multi-region setups, and troubleshooting. ### Beta dashboards Dashboards marked with a **beta** label are recently added and may receive changes to their chart layout and metrics based on feedback. Once a dashboard is stable, the beta label is removed. If you have feedback on any dashboard, [let us know](mailto:support@appsignal.com). ## Dashboard design Every AWS dashboard is designed to help you answer common operational questions quickly: 1. **Is anything broken?** Health indicators and error rates appear first, so a quick glance at the top of the dashboard tells you whether something needs attention. 2. **Why is it slow or failing?** Performance metrics like latency, queue depth, and throttle counts help you narrow down the cause. 3. **Do I need to scale?** CPU, memory, and capacity metrics show whether you are approaching resource limits. Charts are ordered by urgency of signal, not by resource type. Health and stability metrics come first, followed by resource pressure, then operational context like network throughput and storage I/O. Chart descriptions explain what values indicate a problem and what to do about it, rather than restating the metric name. For example, a Lambda Throttles chart tells you that non-zero values mean requests are being dropped and suggests increasing reserved concurrency. ## Supported services The following sections list all AWS services with magic dashboards, grouped by category. Each section includes the service, its CloudWatch namespace (used for [filtering which metrics to stream](/metrics/cloudwatch-cloudformation#filter-specific-aws-services)), and the charts in its dashboard. ## Compute ### EC2 **Namespace:** `AWS/EC2` Monitor Amazon EC2 instance performance including CPU, network, disk, and EBS metrics. Charts: * CPU Utilization * Network In vs Out * Network Packets In vs Out * Disk Read vs Write Ops * Disk Read vs Write Bytes * EBS Read vs Write Ops * EBS Read vs Write Bytes * Status Checks * CPU Credit Balance vs Usage ### Lambda **Namespace:** `AWS/Lambda` Monitor AWS Lambda function invocations, errors, throttles, duration, and concurrency. Charts: * Errors * Throttles * Dead Letter Errors vs Destination Delivery Failures * Invocations * Duration * ConcurrentExecutions vs UnreservedConcurrentExecutions * ClaimedAccountConcurrency * AsyncEventsReceived vs AsyncEventsDropped * AsyncEventAge * Iterator Age ### ECS **Namespace:** `AWS/ECS` Monitor Amazon ECS service-level CPU, memory utilization, and task counts. Charts: * CPU Utilization * Memory Utilization * Running vs Desired Task Count * Pending Task Count ### EKS Nodes **Namespace:** `ContainerInsights` Monitor EKS node-level CPU, memory, filesystem, and network metrics across the cluster. Charts: * Node CPU Utilization * Node Memory Utilization * Node Filesystem Utilization * Node Network Traffic * Running Pods per Node * Running Containers per Node * Cluster Node Count ### EKS Pods **Namespace:** `ContainerInsights` Monitor EKS pod-level CPU, memory, network, and container restart metrics. Charts: * Container Restarts * Pod CPU Utilization * Pod Memory Utilization * Pod Network Rx vs Tx ### Auto Scaling **Namespace:** `AWS/AutoScaling` Monitor Auto Scaling group capacity, instance lifecycle states, and scaling activity. Charts: * Scaling Overview * Instance Lifecycle * Total Instances ### App Runner **Namespace:** `AWS/AppRunner` Monitor AWS App Runner service performance including requests, latency, HTTP status codes, and resource utilization. Charts: * HTTP 2xx vs 4xx vs 5xx * Requests * Request Latency * CPU Utilization * Memory Utilization * Active Instances * Concurrency ## Databases ### RDS **Namespace:** `AWS/RDS` Monitor Amazon RDS database instance performance including CPU, connections, storage, I/O, and replication metrics. Charts: * Replica Lag * CPU Utilization * Freeable Memory * Free Storage Space * Database Connections * Read IOPS vs Write IOPS * Read Latency vs Write Latency * Read Throughput vs Write Throughput * Disk Queue Depth * Swap Usage * Network Receive vs Transmit Throughput * Burst Balance ### Aurora **Namespace:** `AWS/RDS` Monitor Amazon Aurora cluster-specific metrics including replica lag, volume I/O, serverless capacity, and backup storage. Charts: * Aurora Replica Lag * Aurora Replica Lag (Max vs Min) * CPU Utilization * Database Connections * Freeable Memory * Buffer Cache Hit Ratio * Volume Read vs Write IOPs * Volume Bytes Used * Serverless Database Capacity * Backup Storage Used ### DynamoDB **Namespace:** `AWS/DynamoDB` Monitor Amazon DynamoDB table performance including capacity consumption, throttling, latency, and errors. Charts: * Read vs Write Throttle Events * System Errors vs User Errors * Consumed Read vs Write Capacity * Provisioned Read vs Write Capacity * Successful Request Latency * Conditional Check Failed Requests * Returned Item Count * Time To Live Deleted Item Count * Replication Latency * Transaction Conflict ### ElastiCache Redis **Namespace:** `AWS/ElastiCache` Monitor Amazon ElastiCache Redis cluster performance including cache hits/misses, CPU, memory, connections, and replication. Charts: * Cache Hits vs Misses * Cache Hit Rate * Engine CPU Utilization * Current Connections * Evictions * Bytes Used for Cache * Database Memory Usage Percentage * Freeable Memory * Network In vs Out * Replication Lag * Current Items * Commands: Get vs Set * Host CPU Utilization * Memory Fragmentation Ratio ### ElastiCache Memcached **Namespace:** `AWS/ElastiCache` Monitor Amazon ElastiCache Memcached cluster performance including get/set commands, hit rates, CPU, memory, and connections. Charts: * Get Hits vs Misses * Commands: Get vs Set * CPU Utilization * Current Connections * Evictions * Bytes Used for Cache Items vs Freeable Memory * Network In vs Out * Current Items ### OpenSearch **Namespace:** `AWS/ES` Monitor OpenSearch cluster health, resource utilization, search and indexing performance, and HTTP response codes. Charts: * Cluster Status * Nodes * CPU Utilization * Free Storage Space * JVM Memory Pressure * Search vs Indexing Latency * Search vs Indexing Rate * HTTP Response Codes * Threadpool Search * Threadpool Write * Cluster Index Writes Blocked * Automated Snapshot Failure * Master CPU vs JVM Memory Pressure ### Redshift **Namespace:** `AWS/Redshift` Monitor Redshift cluster health, CPU, disk usage, query performance, and I/O throughput. Charts: * Health Status * CPU Utilization * Disk Space Used * Database Connections * Query Throughput * Read vs Write Latency * Read vs Write IOPS * Network Throughput ### DocumentDB **Namespace:** `AWS/DocDB` Monitor Amazon DocumentDB cluster performance including CPU, connections, IOPS, latency, memory, and storage. Charts: * CPU Utilization * Database Connections * Read vs Write IOPS * Read vs Write Latency * Freeable Memory * Volume Bytes Used * Buffer Cache Hit Ratio * Replica Lag ## Networking and content delivery ### ALB (Application Load Balancer) **Namespace:** `AWS/ApplicationELB` Monitor Application Load Balancer request counts, response times, HTTP status codes, host health, and connection metrics. Charts: * HTTP ELB 4xx vs 5xx * Healthy vs Unhealthy Hosts * Target Connection Errors * Rejected Connections * Request Count * Target Response Time * HTTP Target 2xx vs 3xx vs 4xx vs 5xx * Active vs New Connections * Processed Bytes * Consumed LCUs ### Classic ELB **Namespace:** `AWS/ELB` Monitor Classic Elastic Load Balancer request counts, latency, HTTP status codes, host health, and queue metrics. Charts: * HTTP ELB 4xx vs 5xx * Healthy vs Unhealthy Hosts * Backend Connection Errors * Request Count * Latency * HTTP Backend 2xx vs 3xx vs 4xx vs 5xx * Surge Queue Length vs Spillover Count ### CloudFront **Namespace:** `AWS/CloudFront` Monitor Amazon CloudFront distribution request counts, data transfer, error rates, and cache hit rates. Charts: * Total Error Rate * 4xx vs 5xx Error Rate * Requests * Bytes Downloaded vs Uploaded * Cache Hit Rate * Origin Latency ### NLB (Network Load Balancer) **Namespace:** `AWS/NetworkELB` Monitor Network Load Balancer target health, connection flow, throughput, TCP resets, and TLS errors. Charts: * Target Health * TLS Negotiation Errors * Active Connections * New Connections * Processed Bytes * TCP Resets * Consumed LCUs ### NAT Gateway **Namespace:** `AWS/NATGateway` Monitor NAT Gateway throughput, connections, port allocation errors, and packet drops. Charts: * Errors and Drops * Byte Throughput * Packet Throughput * Connections * Peak Utilization ### Route 53 **Namespace:** `AWS/Route53` Monitor Route 53 health check status, endpoint latency, and DNS query volume. Charts: * Health Check Status * Health Check Percentage Healthy * Endpoint Latency * DNS Query Volume ### API Gateway **Namespace:** `AWS/ApiGateway` Monitor Amazon API Gateway request counts, latency, and error rates. Charts: * 4XX Errors * 5XX Errors * Request Count * Latency vs Integration Latency * Cache Hit vs Miss ## Storage ### S3 **Namespace:** `AWS/S3` Monitor Amazon S3 bucket storage size, object counts, request metrics, errors, and latency. Charts: * 4xx vs 5xx Errors * Bucket Size * Number of Objects * All Requests * Request Types * First Byte Latency vs Total Request Latency * Bytes Downloaded vs Uploaded ### EBS **Namespace:** `AWS/EBS` Monitor EBS volume throughput, IOPS, queue length, latency, and burst credit balance. Charts: * Volume Status Check * Read vs Write Bytes * Read vs Write Ops * Queue Length * Read vs Write Time * Idle Time * Burst Balance ### EFS **Namespace:** `AWS/EFS` Monitor EFS throughput, I/O limits, burst credits, client connections, and storage usage. Charts: * Throughput * Permitted Throughput * I/O Limit * Burst Credit Balance * Client Connections * Storage ## Messaging and streaming ### SQS **Namespace:** `AWS/SQS` Monitor Amazon SQS queue message throughput, queue depth, message age, and message size. Charts: * Age of Oldest Message * Queue Depth (Visible vs Not Visible vs Delayed) * Messages Sent vs Received vs Deleted * Sent Message Size * Empty Receives ### SNS **Namespace:** `AWS/SNS` Monitor Amazon SNS topic message publishing, delivery, filtering, and message size. Charts: * Notifications Delivered vs Failed * Messages Published * Notifications Filtered Out * Publish Size ### EventBridge **Namespace:** `AWS/Events` Monitor Amazon EventBridge event matching, rule invocations, failures, dead-letter delivery, and latency. Charts: * Failed Invocations * Dead Letter Invocations * Throttled Rules * Matched Events vs Triggered Rules * Invocations * Ingestion to Invocation Start Latency ### Kinesis Data Streams **Namespace:** `AWS/Kinesis` Monitor Amazon Kinesis Data Streams throughput, iterator age, put/get operations, and provisioned throughput limits. Charts: * GetRecords Iterator Age * Read vs Write Throughput Exceeded * Incoming Records * Incoming Bytes * GetRecords Records vs Bytes * PutRecord vs PutRecords Success * PutRecord vs PutRecords Latency * GetRecords Latency ### Data Firehose **Namespace:** `AWS/Firehose` Monitor Firehose delivery stream ingestion, S3 delivery throughput, data freshness, and delivery success. Charts: * Delivery to S3 - Success * Delivery to S3 - Data Freshness * Incoming Bytes * Incoming Records * Delivery to S3 - Bytes * Delivery to S3 - Records ### MSK (Kafka) **Namespace:** `AWS/Kafka` Monitor MSK cluster health, partition replication, throughput, and resource utilization. Charts: * Cluster Health * Under-Replicated Partitions * Under Min ISR Partitions * Consumer Max Lag * Throughput * Messages In * CPU Usage * Disk Usage ### MQ ActiveMQ **Namespace:** `AWS/AmazonMQ` Monitor Amazon MQ ActiveMQ broker health including CPU, heap, storage, connections, and message throughput. Charts: * Store Usage * CPU Utilization * Heap Usage * Connections * Producers vs Consumers * Total Messages * Enqueue vs Dequeue * Network In vs Out ### MQ RabbitMQ **Namespace:** `AWS/AmazonMQ` Monitor Amazon MQ RabbitMQ broker health including CPU, memory, disk, connections, and message throughput. Charts: * Disk Free vs Limit * Memory Used vs Limit * CPU Utilization * Connections vs Channels * Publish vs Ack Rate * Queue Depth * Consumer Count * Network In vs Out ## Application integration ### Step Functions **Namespace:** `AWS/States` Monitor AWS Step Functions state machine executions, outcomes, throttling, and execution duration. Charts: * Executions Succeeded vs Failed * Executions Aborted vs Timed Out * Execution Throttled * Executions Started * Execution Time ### AppSync **Namespace:** `AWS/AppSync` Monitor AWS AppSync GraphQL API performance including requests, latency, errors, and real-time subscriptions. Charts: * Client Errors vs Server Errors * Requests * Latency * Tokens Consumed * WebSocket Connections * Active Connections vs Subscriptions * Subscription Messages ## Security ### WAF **Namespace:** `AWS/WAFV2` Monitor WAF request filtering decisions including allowed, blocked, and counted requests. Charts: * Request Decisions * Passed Requests ### Cognito **Namespace:** `AWS/Cognito` Monitor Cognito user pool authentication activity, token operations, and API throttling. Charts: * Authentication * Token & Federation * API Calls vs Throttles ## AI and machine learning ### SageMaker **Namespace:** `AWS/SageMaker` Monitor SageMaker endpoint invocations, errors, latency, and resource utilization. Charts: * Invocation Errors * Invocations * Latency * CPU Utilization * Memory Utilization * Disk Utilization ### Bedrock **Namespace:** `AWS/Bedrock` Monitor Amazon Bedrock model invocations, latency, errors, throttles, and token usage. Charts: * Invocation Errors * Throttles * Invocations * Invocation Latency * Input vs Output Tokens * Output Images ## Developer tools ### CodeBuild **Namespace:** `AWS/CodeBuild` Monitor CodeBuild project build counts, success/failure rates, and build phase durations. Charts: * Builds * Build Duration * Queue Duration * Provisioning & Source Download ### CloudWatch Logs **Namespace:** `AWS/Logs` Monitor CloudWatch Logs ingestion volume, log event counts, subscription forwarding, and delivery errors. Charts: * Delivery Errors vs Throttling * Incoming Data * Incoming Log Events * Forwarded Bytes * Forwarded Log Events ## Email ### SES **Namespace:** `AWS/SES` Monitor SES email delivery, bounces, complaints, and sender reputation rates. Charts: * Bounces vs Complaints * Email Sending * Reputation Rates ## Analytics ### Athena **Namespace:** `AWS/Athena` Monitor Athena query execution times, query phase durations, and data scanned. Charts: * Query Execution Time * Query Phases * Data Scanned ### Glue **Namespace:** `AWS/Glue` Monitor Glue ETL job duration, task completion, data throughput, and JVM heap usage. Charts: * Job Duration * Tasks * Bytes Read * JVM Heap * JVM Heap Usage ## Management and monitoring ### Billing **Namespace:** `AWS/Billing` Monitor estimated AWS charges broken down by service. Charts: * Estimated Charges ### CloudTrail **Namespace:** `AWS/CloudTrail` Monitor CloudTrail API event volume. Charts: * Events # Stream AWS CloudWatch metrics through the AWS Console Source: https://docs.appsignal.com/metrics/cloudwatch This guide walks through setting up CloudWatch metrics streaming to AppSignal by creating each resource manually in the AWS Console. For an automated alternative, see [Stream AWS CloudWatch metrics with CloudFormation](/metrics/cloudwatch-cloudformation). For an overview of CloudWatch metrics in AppSignal, including magic dashboards and metric naming, see [AWS CloudWatch metrics](/metrics/cloudwatch-overview). Complete the following steps to send CloudWatch metrics to AppSignal through Amazon Data Firehose: 1. [Set up an S3 bucket for failed deliveries](#set-up-an-s3-bucket-for-failed-deliveries) 2. [Set up an IAM role for Data Firehose](#set-up-an-iam-role-for-data-firehose) 3. [Create a Firehose stream](#create-a-firehose-stream) 4. [Create a CloudWatch metric stream](#create-a-cloudwatch-metric-stream) Before you start, have the following information ready: * Your app's App-level Push API key. To find it, open the [API keys settings page](https://appsignal.com/redirect-to/app?to=api_keys\&key_tab=app), or navigate to your organization settings and select **Dev zone > API keys**. * The AWS region you want to stream metrics from. * AWS permissions to create Firehose streams, CloudWatch metric streams, S3 buckets, and IAM roles. ## Set up an S3 bucket for failed deliveries Amazon Data Firehose requires an S3 bucket to store records that fail to deliver. Create an S3 bucket through the AWS Console or CLI before proceeding. ## Set up an IAM role for Data Firehose Create an IAM role that allows Data Firehose to write to the S3 bucket. Use the following trust policy: ```json JSON theme={null} { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "firehose.amazonaws.com" }, "Action": "sts:AssumeRole" } ] } ``` Assign the following permissions policy to the role as an inline policy. <Note> See [Adding IAM identity permissions](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_manage-attach-detach.html) for instructions on creating inline policies for IAM roles. </Note> ```json JSON theme={null} { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:AbortMultipartUpload", "s3:GetBucketLocation", "s3:GetObject", "s3:ListBucket", "s3:ListBucketMultipartUploads", "s3:PutObject" ], "Resource": [ "arn:aws:s3:::<FIREHOSE_S3_BUCKET>", "arn:aws:s3:::<FIREHOSE_S3_BUCKET>/*" ] } ] } ``` Replace `<FIREHOSE_S3_BUCKET>` with the name of the S3 bucket you created in the previous step. ## Create a Firehose stream 1. Open the Amazon Data Firehose console and select **Create Firehose stream**. 2. Select **Direct PUT** as the source. 3. Select **HTTP Endpoint** as the destination. 4. Under "Transform records", leave data transformation turned off. The data must be delivered as-is. 5. Enter the following URL as the **HTTP endpoint URL**: ```shell Shell theme={null} https://appsignal-endpoint.net/metrics/aws-cloudwatch ``` 6. Enter your app's App-level Push API key as the **Access key**. This is not an AWS access key. It is the key AppSignal uses to identify your app. 7. Under "Content encoding", select **GZIP**. 8. Under "Buffer hints", set the buffer size to **1 MB** and the buffer interval to **60 seconds** for the lowest latency. Higher values reduce cost but increase delivery delay. 9. Under "Backup settings", set source record backup to **Failed data only** and select the S3 bucket you created in the previous steps. 10. Under "Advanced settings > Service access", select **Choose existing IAM role** and choose the IAM role you created in the previous steps. 11. Select **Create Firehose stream**. ## Create a CloudWatch metric stream 1. In the CloudWatch console, go to **Metrics > Streams**. 2. Select **Create metric stream**. 3. Select **Custom setup with Firehose**. Under **Select your Amazon Data Firehose stream**, choose the Firehose stream you created in the previous step. 4. Choose which metrics to stream: * **All metrics** streams everything from all AWS services. This is the simplest option, but may increase costs. * **Selected namespaces** lets you include or exclude specific namespaces, such as `AWS/EC2`, `AWS/Lambda`, or `AWS/RDS`. See the [magic dashboards](/metrics/aws-dashboards) page for the services AppSignal supports. 5. Select **OpenTelemetry 1.0** as the output format. 6. For **Service access**, let the AWS Console create or update the IAM role for you, or choose an existing role with permission to write to the Firehose stream. 7. Select **Create metric stream**. You can create multiple metric streams if you need to send metrics to different destinations or filter metrics differently for separate use cases. ## Verify the setup After completing the setup, allow 5 to 10 minutes for metrics to begin appearing in AppSignal. To verify data is flowing: 1. Check the **Monitoring** tab on your Firehose stream in the AWS Console. Look for non-zero **Incoming records** and **HTTP endpoint - Success** metrics. 2. Confirm the metric stream state shows **Running** in the CloudWatch console under **Metrics > Streams**. If no data appears, enable CloudWatch Logs error logging on the Firehose stream and check for delivery errors. <Note> Some AWS metrics, such as S3 daily storage metrics, are reported with timestamps older than two hours and do not appear in metric streams. See the [AWS CloudWatch Metric Streams documentation](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch-Metric-Streams.html) for details on metric reporting frequencies. </Note> ## CloudWatch metrics in AppSignal After setup, AppSignal receives metrics from any AWS service that emits metrics through CloudWatch. AppSignal automatically creates [magic dashboards](/metrics/aws-dashboards) for supported AWS services when it detects their metrics. These dashboards appear in **Dashboards** with pre-built charts for the most important metrics of each service. You can also build your own views using [custom dashboards](/metrics/dashboards). In the **Metric** field, type `aws_` to browse the CloudWatch metrics AppSignal has received. AppSignal normalizes CloudWatch metric names to lowercase with underscores. For example, `AWS/Firehose` `DeliveryToS3.Success` becomes `aws_firehose_delivery_to_s3_success`. It can take a few minutes after setup for the first metrics to appear. If the list is empty, wait a few minutes and refresh. If you need help, [contact us](mailto:support@appsignal.com). # Stream AWS CloudWatch metrics with CloudFormation Source: https://docs.appsignal.com/metrics/cloudwatch-cloudformation Use an AWS CloudFormation template to set up CloudWatch metrics streaming to AppSignal. The template creates all required resources in a single deployment, instead of configuring each one manually through the AWS Console. For an overview of CloudWatch metrics in AppSignal, including magic dashboards and metric naming, see [AWS CloudWatch metrics](/metrics/cloudwatch-overview). If you prefer to set up each resource manually, see the [console setup guide](/metrics/cloudwatch). ## Before you start Have the following information ready: * Your app's App-level Push API key. To find it, open the [API keys settings page](https://appsignal.com/redirect-to/app?to=api_keys\&key_tab=app), or navigate to your organization settings and select **Dev zone > API keys**. * The AWS region where you want to deploy the stack ## What the template creates The CloudFormation template creates the following resources: 1. An **S3 bucket** to store records that fail to deliver, with a 30-day lifecycle expiration and a retain-on-delete policy. 2. An **IAM role** that allows Amazon Data Firehose to write failed records to the S3 bucket. 3. A **Firehose delivery stream** that sends metrics to the AppSignal endpoint over HTTPS. 4. An **IAM role** that allows CloudWatch Metric Streams to write to the Firehose delivery stream. 5. A **CloudWatch metric stream** that exports metrics in OpenTelemetry 1.0 format. ## CloudFormation template Copy the following template and save it as `appsignal-cloudwatch-metrics.yaml`: ```yaml YAML theme={null} AWSTemplateFormatVersion: "2010-09-09" Description: > Stream CloudWatch metrics to AppSignal using Amazon Data Firehose. Metadata: AWS::CloudFormation::Interface: ParameterGroups: - Label: default: AppSignal Configuration Parameters: - AppLevelPushApiKey ParameterLabels: AppLevelPushApiKey: default: "App-level Push API Key (find at https://appsignal.com/redirect-to/app?to=api_keys&key_tab=app)" Parameters: AppLevelPushApiKey: Type: String NoEcho: true Description: > Your App-level Push API key from AppSignal. Resources: # 1. S3 bucket for failed deliveries FailedDeliveryBucket: Type: AWS::S3::Bucket DeletionPolicy: Retain Properties: BucketName: !Sub "appsignal-firehose-${AWS::StackName}-${AWS::AccountId}-${AWS::Region}" PublicAccessBlockConfiguration: BlockPublicAcls: true BlockPublicPolicy: true IgnorePublicAcls: true RestrictPublicBuckets: true BucketEncryption: ServerSideEncryptionConfiguration: - ServerSideEncryptionByDefault: SSEAlgorithm: AES256 LifecycleConfiguration: Rules: - Id: ExpireFailedDeliveries Status: Enabled ExpirationInDays: 30 # 2. IAM role for Firehose to write to S3 FirehoseS3Role: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Principal: Service: firehose.amazonaws.com Action: "sts:AssumeRole" Policies: - PolicyName: FirehoseS3Access PolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Action: - "s3:AbortMultipartUpload" - "s3:GetBucketLocation" - "s3:GetObject" - "s3:ListBucket" - "s3:ListBucketMultipartUploads" - "s3:PutObject" Resource: - !GetAtt FailedDeliveryBucket.Arn - !Sub "${FailedDeliveryBucket.Arn}/*" # 3. Firehose delivery stream MetricsDeliveryStream: Type: AWS::KinesisFirehose::DeliveryStream Properties: DeliveryStreamType: DirectPut HttpEndpointDestinationConfiguration: EndpointConfiguration: Url: "https://appsignal-endpoint.net/metrics/aws-cloudwatch" AccessKey: !Ref AppLevelPushApiKey Name: AppSignal RequestConfiguration: ContentEncoding: GZIP BufferingHints: IntervalInSeconds: 60 SizeInMBs: 1 S3BackupMode: FailedDataOnly S3Configuration: BucketARN: !GetAtt FailedDeliveryBucket.Arn RoleARN: !GetAtt FirehoseS3Role.Arn RoleARN: !GetAtt FirehoseS3Role.Arn # 4. IAM role for CloudWatch Metric Streams to write to Firehose MetricStreamRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Principal: Service: streams.metrics.cloudwatch.amazonaws.com Action: "sts:AssumeRole" Policies: - PolicyName: MetricStreamFirehoseAccess PolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Action: - "firehose:PutRecord" - "firehose:PutRecordBatch" Resource: !GetAtt MetricsDeliveryStream.Arn # 5. CloudWatch metric stream CloudWatchMetricStream: Type: AWS::CloudWatch::MetricStream Properties: FirehoseArn: !GetAtt MetricsDeliveryStream.Arn RoleArn: !GetAtt MetricStreamRole.Arn OutputFormat: "opentelemetry1.0" Outputs: DeliveryStreamName: Description: Name of the Firehose delivery stream. Value: !Ref MetricsDeliveryStream MetricStreamName: Description: Name of the CloudWatch metric stream. Value: !Ref CloudWatchMetricStream FailedDeliveryBucketName: Description: S3 bucket for failed delivery records. Value: !Ref FailedDeliveryBucket ``` ## Deploy the stack 1. Open the [AWS CloudFormation console](https://console.aws.amazon.com/cloudformation/). 2. Select **Create stack** and choose **With new resources (standard)**. 3. Under **Specify template**, select **Upload a template file** and upload `appsignal-cloudwatch-metrics.yaml`. 4. Select **Next**. 5. Enter a stack name, for example `appsignal-cloudwatch-metrics`. 6. For **AppLevelPushApiKey**, enter your app's App-level Push API key. 7. Select **Next** twice, then check **I acknowledge that AWS CloudFormation might create IAM resources** and select **Submit**. The stack takes a few minutes to create. Once the status shows **CREATE\_COMPLETE**, CloudWatch begins streaming metrics to AppSignal. ## Filter specific AWS services By default, the template streams metrics from all AWS services in the account. To stream only specific services, add `IncludeFilters` to the `CloudWatchMetricStream` resource: ```yaml YAML theme={null} CloudWatchMetricStream: Type: AWS::CloudWatch::MetricStream Properties: FirehoseArn: !GetAtt MetricsDeliveryStream.Arn RoleArn: !GetAtt MetricStreamRole.Arn OutputFormat: "opentelemetry1.0" IncludeFilters: - Namespace: AWS/EC2 - Namespace: AWS/RDS - Namespace: AWS/ELB ``` Replace the namespaces with the AWS services you want to monitor. See the [AWS services that publish CloudWatch metrics](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/aws-services-cloudwatch-metrics.html) for a full list of available namespaces. ## Verify the deployment 1. In the AWS Console, search for "CloudFormation" and select **Stacks**. Open your stack and select the **Resources** tab to confirm all resources show **CREATE\_COMPLETE**. 2. In the AWS Console, search for "CloudWatch". In the left sidebar, go to **Metrics > Streams** and confirm the metric stream status is **Running**. 3. In the AWS Console, search for "Firehose". Open the delivery stream and use the **Test with demo data** function to verify connectivity. 4. In AppSignal, open your [app's dashboard](https://appsignal.com/redirect-to/app?to=dashboard) and check that CloudWatch metrics appear on your [custom dashboard](/metrics/dashboards). If metrics do not appear after a few minutes, check the S3 bucket for failed delivery records. If you need help, [contact us](mailto:support@appsignal.com). ## Multi-region deployments The template deploys all resources in a single AWS region. If you run workloads in multiple regions, deploy a separate copy of this stack in each region. This keeps data transfer within each region and avoids cross-region transfer fees. ## Clean up To remove all resources created by this template, delete the stack in the CloudFormation console. The S3 bucket for failed deliveries has a `DeletionPolicy` of `Retain`, so it is kept when the stack is deleted to avoid losing any failed delivery records. Failed delivery records in the bucket are automatically deleted after 30 days by the lifecycle rule. You can delete the bucket manually once you no longer need it. # AWS CloudWatch metrics Source: https://docs.appsignal.com/metrics/cloudwatch-overview AppSignal can receive and visualize metrics from your AWS infrastructure through CloudWatch Metric Streams. Once connected, AppSignal automatically creates [magic dashboards](/metrics/aws-dashboards) for the AWS services you use, giving you pre-built charts for the metrics that matter most. ## How it works AWS CloudWatch collects metrics from services running in your AWS account. A CloudWatch Metric Stream exports those metrics through Amazon Data Firehose to AppSignal's HTTP endpoint in OpenTelemetry format. The data flow looks like this: **AWS services** β†’ **CloudWatch** β†’ **Metric Stream** β†’ **Data Firehose** β†’ **AppSignal** Once metrics arrive, AppSignal normalizes the metric names, applies tags from CloudWatch dimensions, and stores them as time series data. When AppSignal detects metrics from a supported AWS service, it creates a magic dashboard with pre-built charts for that service. ## Set up CloudWatch metrics There are two ways to connect CloudWatch metrics to AppSignal: ### Console setup Follow the instructions to create a Firehose delivery stream, an S3 backup bucket, and a CloudWatch Metric Stream through the AWS Console. See [Stream AWS CloudWatch metrics through the AWS Console](/metrics/cloudwatch). ### CloudFormation Deploy a single CloudFormation template that creates all the required resources in one step. This is the fastest way to get started and the easiest to reproduce across AWS accounts or regions. See [Stream AWS CloudWatch metrics with CloudFormation](/metrics/cloudwatch-cloudformation). ## Magic dashboards AppSignal automatically creates dashboards when it detects CloudWatch metrics from a supported AWS service. Each dashboard is designed to answer common operational questions: is anything broken, why is it slow, and do I need to scale? Dashboards put health and error indicators first, followed by resource utilization, then operational context. Chart descriptions explain what values indicate a problem and what to do about it, so you do not need to be an AWS monitoring expert to interpret your data. AppSignal supports magic dashboards for over 45 AWS services across compute, databases, networking, storage, messaging, and more. See [AWS magic dashboards](/metrics/aws-dashboards) for the full list of supported services and their charts. ## Choose which metrics to stream CloudWatch Metric Streams can send metrics from all AWS services in your account or a filtered subset. Streaming all metrics is the simplest option. If you only need specific services, filter by namespace to limit the data sent through Firehose. To filter, add `IncludeFilters` to the Metric Stream resource, specifying the CloudWatch namespaces you want (such as `AWS/EC2`, `AWS/Lambda`, or `AWS/RDS`). See the [AWS magic dashboards](/metrics/aws-dashboards) page for the namespace of each supported service. For filtering configuration examples, see the [CloudFormation setup guide](/metrics/cloudwatch-cloudformation#filter-specific-aws-services). ## Metric naming AppSignal normalizes CloudWatch metric names to lowercase with underscores. The format is the normalized namespace followed by the `snake_case` metric name. For example, `AWS/Lambda` `Duration` becomes `aws_lambda_duration`, and `AWS/Firehose` `DeliveryToS3.Success` becomes `aws_firehose_delivery_to_s3_success`. You can use these normalized names when building [custom dashboards](/metrics/dashboards) or setting up [anomaly detection](/metrics/dashboards) in AppSignal. ## Tags and dimensions CloudWatch dimensions (such as `FunctionName`, `DBInstanceIdentifier`, or `ServiceName`) become tags in AppSignal. Use these tags to filter charts by specific resources. Magic dashboards use wildcard tag filters to show all resources of a given type as separate lines on the same chart. You can also use these tags in custom dashboards for more focused views. ## Multi-region and multi-account setups CloudWatch Metric Streams operate within a single AWS region. If you run workloads in multiple regions, deploy a separate Metric Stream and Firehose delivery stream in each region. The [CloudFormation template](/metrics/cloudwatch-cloudformation) can be deployed once per region to set this up. For multi-account setups, create a Metric Stream in each account. Use the same App-level Push API key to send all metrics to a single AppSignal app, or use different keys to separate metrics across apps. ## Troubleshooting If metrics do not appear in AppSignal after setup: 1. Check the **Monitoring** tab on your Firehose delivery stream in the AWS Console. Look for non-zero **Incoming records** and **HTTP endpoint - Success** metrics. 2. Verify the Metric Stream state shows **Running** in the CloudWatch console under **Metrics > Streams**. 3. Check the S3 backup bucket for failed delivery records. 4. Confirm the output format is set to **OpenTelemetry 1.0**. Other formats are not supported. Some AWS metrics (such as S3 daily storage metrics) are reported with timestamps older than two hours and do not appear in Metric Streams. See the [AWS documentation on CloudWatch Metric Streams](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch-Metric-Streams.html) for details on metric reporting frequencies. If you need help, [contact us](mailto:support@appsignal.com). # Custom metrics Source: https://docs.appsignal.com/metrics/custom Custom metrics let you track anything meaningful in your application β€” from the number of active users at a given moment, to how many invoices were generated in the last hour, to the current size of your database. By sending custom metrics to AppSignal, you can create graphs in your dashboards that relate this data to critical signals like error rates and response times, giving you the context to quickly identify and resolve issues. Additionally, custom metrics help you work proactively rather than reactively. While logging helps you debug issues after they occur, custom metrics let you spot trends and potential problems before your customers notice. You can concentrate on data that matters to your business β€” such as active user counts, KPIs, or sales volumes β€” without sifting through log lines or incident lists. You can also set triggers on custom metrics to warn you when values fall outside expected ranges. Custom metrics are not a replacement for [custom instrumentation](/ruby/instrumentation/instrumentation), but a complementary tool for making specific application data visible and measurable over time. AppSignal offers three custom metric types: | Type | Best for | Example use case | | --------------------------- | ------------------------------------- | ------------------------------------------ | | [Gauge](#gauge) | Absolute values that change over time | Active users, database size, disk usage | | [Measurement](#measurement) | Ranges and distributions of values | Response times, job durations, cart values | | [Counter](#counter) | Counting occurrences over time | Invoices created, logins, errors triggered | You can track custom metrics in [graphs](#graphing-custom-metrics) in your AppSignal dashboards. ### Gauge A gauge records a value at a specific point in time. If you report multiple gauges with the same key within the same time window, only the last value is persisted. **Use gauges when** you want to know the current state of something β€” the number of items that exist right now, or the current size of a resource. All AppSignal [host metrics](/metrics/host-metrics) are stored as gauges. Gauges are often used with [minutely probes](/ruby/instrumentation/minutely-probes) to periodically report a snapshot value, such as querying the number of recently active shopping carts or open database connections every minute. **Examples:** active user count, database size, disk usage, number of open connections. <CodeGroup> ```ruby Ruby theme={null} # The first argument is a string, the second argument a number # Appsignal.set_gauge(metric_name, value) Appsignal.set_gauge("database_size", 100) Appsignal.set_gauge("database_size", 10) # Will create the metric "database_size" with the value 10 ``` ```elixir Elixir theme={null} # The first argument is a string, the second argument a number # Appsignal.set_gauge(metric_name, value) Appsignal.set_gauge("database_size", 100) Appsignal.set_gauge("database_size", 10) # Will create the metric "database_size" with the value 10 ``` ```javascript Node.js theme={null} const meter = Appsignal.client.metrics(); // The first argument is a string, the second argument a number // meter.setGauge(metric_name, value) meter.setGauge("database_size", 100); meter.setGauge("database_size", 10); // Will create the metric "database_size" with the value 10 ``` ```python Python theme={null} # Import the AppSignal metric helper from appsignal import set_gauge # The first argument is a string, the second argument a number (int/float) # set_gauge(metric_name, value) set_gauge("database_size", 100) set_gauge("database_size", 10) # Will create the metric named "database_size" with the value 10 ``` ```php PHP theme={null} <?php use Appsignal\Appsignal; // Record gauge values Appsignal::setGauge('database_size', 100); Appsignal::setGauge('database_size', 10); // Will create the metric "database_size" with the value 10 ``` ```java Java theme={null} import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.metrics.DoubleGauge; import io.opentelemetry.api.metrics.Meter; public void recordMetrics() { // Get the meter from the global meter provider Meter meter = GlobalOpenTelemetry.getMeter("my-app"); // Create a gauge instrument DoubleGauge gauge = meter.gaugeBuilder("database_size").build(); // Record gauge values gauge.set(100); gauge.set(10); // Will create the metric "database_size" with the value 10 } ``` ```go Go theme={null} package main import ( "context" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/metric" ) func recordMetrics() { // Get the meter from the global meter provider meter := otel.Meter("my-app") // Create a gauge instrument gauge, _ := meter.Float64Gauge("database_size") // Record gauge values gauge.Record(context.Background(), 100) gauge.Record(context.Background(), 10) // Will create the metric "database_size" with the value 10 } ``` </CodeGroup> <Tip> Starting from version 3.1.0, the Node.js integration allows you to set gauges and counters using the OpenTelemetry metrics provider. You must enable the agent's OpenTelemetry HTTP server to report these metrics to AppSignal; you can do this by setting the [enableOpentelemetryHttp](/nodejs/3.x/configuration/options#option-enable_opentelemetry_http) option to `true`. The Java and Go integrations also use OpenTelemetry metrics to report custom metrics to AppSignal. You can read more about OpenTelemetry metrics in the [OpenTelemetry metrics documentation](https://opentelemetry.io/docs/concepts/metrics/). For Node.js, see the [OpenTelemetry JS metrics documentation](https://opentelemetry.io/docs/languages/js/instrumentation/#metrics) for more information. </Tip> ### Measurement A measurement tracks a spread of values over time. AppSignal stores the average and count for each time window, letting you graph things like average duration, 90th/95th percentile, and throughput. **Use measurements when** you are recording a value that varies across individual events and you want to understand its distribution β€” not just its current value. For example, you can track the duration of a critical background job (such as order confirmation emails) to spot slowdowns before they affect your users. A measurement metric creates several metric fields: * **Count:** how many times the helper was called. Useful for throughput graphs. * **Mean:** the average metric value for the point in time. * **90th percentile:** the 90th percentile of the metric value for the point in time. * **95th percentile:** the 95th percentile of the metric value for the point in time. **Examples:** HTTP response times, background job durations, user cart values, query execution times. <CodeGroup> ```ruby Ruby theme={null} # The first argument is a string, the second argument a number # Appsignal.add_distribution_value(metric_name, value) Appsignal.add_distribution_value("memory_usage", 100) Appsignal.add_distribution_value("memory_usage", 110) # Will create a metric "memory_usage" with the mean field value 105 # Will create a metric "memory_usage" with the count field value 2 ``` ```elixir Elixir theme={null} # The first argument is a string, the second argument a number # Appsignal.add_distribution_value(metric_name, value) Appsignal.add_distribution_value("memory_usage", 100) Appsignal.add_distribution_value("memory_usage", 110) # Will create a metric "memory_usage" with the mean field value 105 # Will create a metric "memory_usage" with the count field value 2 ``` ```javascript JavaScript theme={null} const meter = Appsignal.client.metrics(); // The first argument is a string, the second argument a number // meter.addDistributionValue(metric_name, value) meter.addDistributionValue("memory_usage", 100); meter.addDistributionValue("memory_usage", 110); // Will create a metric "memory_usage" with the mean field value 105 // Will create a metric "memory_usage" with the count field value 2 ``` ```python Python theme={null} # Import the AppSignal metric helper from appsignal import add_distribution_value # The first argument is a string, the second argument a number (int/float) # add_distribution_value(metric_name, value) add_distribution_value("memory_usage", 100) add_distribution_value("memory_usage", 110) # Will create a metric "memory_usage" with the mean field value 105 # Will create a metric "memory_usage" with the count field value 2 ``` ```php PHP theme={null} <?php use Appsignal\Appsignal; // Record distribution values Appsignal::addDistributionValue('memory_usage', 100); Appsignal::addDistributionValue('memory_usage', 110); // Will create a metric "memory_usage" with the mean field value 105 // Will create a metric "memory_usage" with the count field value 2 ``` ```java Java theme={null} import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.metrics.DoubleHistogram; import io.opentelemetry.api.metrics.Meter; public void recordDistributions() { // Get the meter from the global meter provider Meter meter = GlobalOpenTelemetry.getMeter("my-app"); // Create a histogram instrument for distributions DoubleHistogram histogram = meter.histogramBuilder("memory_usage").build(); // Record distribution values histogram.record(100); histogram.record(110); // Will create a metric "memory_usage" with the mean field value 105 // Will create a metric "memory_usage" with the count field value 2 } ``` ```go Go theme={null} package main import ( "context" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/metric" ) func recordDistributions() { // Get the meter from the global meter provider meter := otel.Meter("my-app") // Create a histogram instrument for distributions histogram, _ := meter.Float64Histogram("memory_usage") // Record distribution values histogram.Record(context.Background(), 100) histogram.Record(context.Background(), 110) // Will create a metric "memory_usage" with the mean field value 105 // Will create a metric "memory_usage" with the count field value 2 } ``` </CodeGroup> ### Counter A counter accumulates a total count over a time window. Counter values are summed for each resolution β€” so at minutely resolution it shows the total for that minute, and at hourly resolution it shows the total for that hour. **Use counters when** you want to track how many times something happened, not what value it had. Counters are especially useful for monitoring the frequency of business-critical events. For example, by tracking both orders placed and invoices created, you can verify that these related counters stay in sync and catch discrepancies early. When the helper is called multiple times, the total/sum of all calls is persisted. Counters are non-monotonic: both positive and negative values are supported, so you can increment and decrement the same counter. For monotonic counters from other systems, there is no validation that counter values only ever increase. **Examples:** orders placed, invoices created, user logins, background jobs queued, failed payment attempts. <Tip> **Gauge vs. Counter:** Use a gauge to track *how many of something exist right now* (e.g., currently active users). Use a counter to track *how many times something happened* in a given period (e.g., new logins in the last minute). </Tip> <CodeGroup> ```ruby Ruby theme={null} # The first argument is a string, the second argument a number # Appsignal.increment_counter(metric_name, value) Appsignal.increment_counter("login_count", 1) Appsignal.increment_counter("login_count", 1) # Will create the metric "login_count" with the value 2 for a point in the minutely/hourly resolution ``` ```elixir Elixir theme={null} # The first argument is a string, the second argument a number # Appsignal.increment_counter(metric_name, value) Appsignal.increment_counter("login_count", 1) Appsignal.increment_counter("login_count", 1) # Will create the metric "login_count" with the value 2 for a point in the minutely/hourly resolution ``` ```javascript JavaScript theme={null} const meter = Appsignal.client.metrics(); // The first argument is a string, the second argument a number // meter.incrementCounter(metric_name, value) meter.incrementCounter("login_count", 1); meter.incrementCounter("login_count", 1); // Will create the metric "login_count" with the value 2 for a point in the minutely/hourly resolution ``` ```python Python theme={null} # Import the AppSignal metric helper from appsignal import increment_counter # The first argument is a string, the second argument a number (int/float) # increment_counter(metric_name, value) increment_counter("metric_name", 1) # Increase the value by one increment_counter("metric_name", 1) increment_counter("metric_name", -1) # Decrease the value by one # Will create the metric named "metric_name" with the value 2 for a point in the minutely/hourly resolution ``` ```php PHP theme={null} <?php use Appsignal\Appsignal; // Record counter values Appsignal::incrementCounter('login_count', 1); Appsignal::incrementCounter('login_count', 1); // Will create the metric "login_count" with the value 2 for a point in the minutely/hourly resolution ``` ```java Java theme={null} import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.metrics.LongCounter; import io.opentelemetry.api.metrics.Meter; public void recordCounters() { // Get the meter from the global meter provider Meter meter = GlobalOpenTelemetry.getMeter("my-app"); // Create a counter instrument LongCounter counter = meter.counterBuilder("login_count").build(); // Record counter values counter.add(1); counter.add(1); // Will create the metric "login_count" with the value 2 for a point in the minutely/hourly resolution } ``` ```go Go theme={null} package main import ( "context" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/metric" ) func recordCounters() { // Get the meter from the global meter provider meter := otel.Meter("my-app") // Create a counter instrument counter, _ := meter.Int64Counter("login_count") // Record counter values counter.Add(context.Background(), 1) counter.Add(context.Background(), 1) // Will create the metric "login_count" with the value 2 for a point in the minutely/hourly resolution } ``` </CodeGroup> <Warning> **Note**: In AppSignal, counters are designed to store integer values only. While the API accepts float values to facilitate integration, these values are internally converted to integers. Decimal values are rounded down to the nearest integer. The value 0.0001 becomes 0, and 1.2, 1.5, and 1.7 become 1. </Warning> ## Metric naming We recommend naming your metrics something easily recognizable. While you can wildcard parts of the metric name for dashboard creation, we recommend you only use this for small grouping and not use IDs in metric names. Metric names only support numbers, letters, dots and underscores (`[a-z0-9._]`) as valid characters. Any other characters will be replaced with an underscore by our processor. You can find the list of metrics as processed on the ["Add Dashboard"](https://appsignal.com/redirect-to/app?to=dashboard\&overlay=dashboardForm). Some examples of good metric names are: * `database_size` * `account_count` * `users.count` * `notifier.failed` * `notifier.perform` * `notifier.success` By default AppSignal already tracks metrics for your application, such as [host metrics](/metrics/host-metrics). See the metrics list on the ["Add Dashboard"](https://appsignal.com/redirect-to/app?to=dashboard\&overlay=dashboardForm) page for the metrics that are already available for your app. <Warning> **Note**: We **do not** recommend adding dynamic values to your metric names like so: `eu.database_size`, `us.database_size` and `asia.database_size`. This creates multiple metrics that serve the same purpose. Instead we recommend using [metric tags](#metric-tags) for this. </Warning> ## Metric values Metrics only support numbers as valid values. Any other value will be silently ignored or will raise an error as triggered by the implementation language number parser. For Ruby and Elixir we support a [double](https://en.wikipedia.org/wiki/Double-precision_floating-point_format) and [integer](https://en.wikipedia.org/wiki/Integer) as valid values: <CodeGroup> ```ruby Ruby theme={null} # Integer Appsignal.increment_counter("login_count", 1) # Double Appsignal.increment_counter("assignment_completed", 0.12) ``` ```elixir Elixir theme={null} # Integer Appsignal.increment_counter("login_count", 1) # Double Appsignal.increment_counter("assignment_completed", 0.12) ``` ```javascript JavaScript theme={null} const meter = Appsignal.client.metrics(); // Integer meter.incrementCounter("login_count", 1); // Double meter.incrementCounter("assignment_completed", 0.12); ``` ```python Python theme={null} from appsignal import increment_counter # Integer increment_counter("login_count", 1) # Double increment_counter("assignment_completed", 0.12) ``` ```php PHP theme={null} <?php use Appsignal\Appsignal; // Integer Appsignal::incrementCounter('login_count', 1); // Double Appsignal::incrementCounter('login_count', 0.12); ``` ```java Java theme={null} import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.metrics.DoubleCounter; import io.opentelemetry.api.metrics.LongCounter; import io.opentelemetry.api.metrics.Meter; public void recordValues() { Meter meter = GlobalOpenTelemetry.getMeter("my-app"); // Integer counter LongCounter longCounter = meter.counterBuilder("login_count").build(); longCounter.add(1); // Double counter DoubleCounter doubleCounter = meter.counterBuilder("assignment_completed") .ofDoubles() .build(); doubleCounter.add(0.12); } ``` ```go Go theme={null} package main import ( "context" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/metric" ) func recordValues() { meter := otel.Meter("my-app") // Integer counter intCounter, _ := meter.Int64Counter("login_count") intCounter.Add(context.Background(), 1) // Float counter floatCounter, _ := meter.Float64Counter("assignment_completed") floatCounter.Add(context.Background(), 0.12) } ``` </CodeGroup> Note: In Node.js, only the `number` type is a valid value. ### Value formatting AppSignal graphs have several display formats, such as numbers, file sizes, durations, etc. These formats help in presenting the metric values in a human-readable way. Selecting a value formatter input does not affect the data stored in our systems, only how it's displayed. To show metric values correctly using these formatters, please check the table below how the value should be reported. | Formatter | Reported value | Description | | ---------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | Number | Display value | A human-readable formatted number. The values should be reported on the same scale as they are displayed. The value `1` is displayed as "`1`", `10_000` as "`10 K`" and `1_000_000` is displayed as "`1 M`". | | Percentage | Display value | A metric value formatted as a percentage. The values should be reported on the same scale as they are displayed. The value `40` is displayed as "`40 %`". | | Throughput | Display value | A metric value formatted as requests per minute/hour. The values should be reported on the same scale as they are displayed. It will display the throughput formatted as a number for both the minute and the hour. The value `10_000` is displayed "`10k / hour 166 / min`". Commonly used for [`counter`](#counter) metrics. | | Duration | Milliseconds | A duration of time. The values should be reported as milliseconds. The value `100` is displayed as "`100 ms`" and 60\_000 as "`60 sec`". Commonly used for [`measurement`](/metrics/custom#measurement) metric. | | File size | [Customizable](#file-size) | A file size formatted as megabytes by default. `1.0` megabytes is displayed as `1Mb`. What file size unit the reported metric value is read as can be customized in the graph builder. | #### File size Metric values that represent a file size can use the file size formatter. To specify which unit of size the reported value is the file size formatter allows for several input values. The available options are: * `Size in Bit` * `Size in Bytes` * `Size in Kilobits` * `Size in Kilobytes` * `Size in Megabytes` When sending a metric with the following value: <CodeGroup> ```ruby Ruby theme={null} Appsignal.set_gauge("database_size", 1024) ``` ```elixir Elixir theme={null} Appsignal.set_gauge("database_size", 1024) ``` ```javascript JavaScript theme={null} const meter = Appsignal.client.metrics(); meter.setGauge("database_size", 1024); ``` ```python Python theme={null} # Import the AppSignal metric helper from appsignal import set_gauge set_gauge("database_size", 1024) ``` ```php PHP theme={null} <?php use Appsignal\Appsignal; Appsignal::setGauge('database_size', 1024); ``` ```java Java theme={null} import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.metrics.DoubleGauge; import io.opentelemetry.api.metrics.Meter; public void recordFileSize() { Meter meter = GlobalOpenTelemetry.getMeter("my-app"); DoubleGauge gauge = meter.gaugeBuilder("database_size").build(); gauge.set(1024); } ``` ```go Go theme={null} package main import ( "context" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/metric" ) func recordFileSize() { meter := otel.Meter("my-app") gauge, _ := meter.Float64Gauge("database_size") gauge.Record(context.Background(), 1024) } ``` </CodeGroup> The graph will render the following display value for the specified file size formatter: * `Size in Bit` will render "128 Bytes" * `Size in Bytes` will render "1 KB" * `Size in Kilobits` will render "128 KB" * `Size in Kilobytes` will render "1 MB" * `Size in Megabytes` will render "1 GB" ## Metric tags <Tip> Custom metric tags require the following AppSignal package/gem version or higher: <ul> <li>Ruby gem version `2.6.0`</li> <li>Elixir package `1.6.0`</li> <li>Node.js package `1.0.0`</li> <li>Python package `0.3.0`</li> </ul> </Tip> A single metric can consist of various groups of data; for example, a 'total\_orders' custom metric could consist of pending and processed orders. You can add multiple tags to metrics for deeper insights into the metric data AppSignal is reporting. Each tag will be represented by its line on an AppSignal graph. By default, the AppSignal metric helpers do not set tags on a custom metric. How you can use tags in AppSignal graphs: Tags can "label" a line in the graph legend, making it easier to see what each line represents when you hover your mouse over them. Filtering with tags can show the same metric in different contexts on different graphs. To get the most out of metric tags, we advise the following: * **Be consistent with tagging:** For optimal tracking and graph legibility, we advise against reporting a custom metric both with and without tags. Reporting the same metric in different ways can create confusion and make it difficult to interpret the data accurately. * **Always use the same metric tags when:** We recommend using the same combination of tags whenever you report a metric. For example, if a metric uses tags A and B in one area of your app, it should use them in all areas. Avoid changing the tags, as consistent tagging will make graphing easier. * **Use a limited range of values for metric tags:** To avoid overly complex or illegible graphs, we recommend using a limited range of tags on your custom metrics, such as regions (EU, US, and Asia). You can perform a broader analysis of your app's metric data when using a limited and precise range of tags for all of your app metric data. In general when implementing metric tagging, consider developing a robust tagging strategy that can be applied consistently across your application and will need little to no adjustments in the long term. <CodeGroup> ```ruby Ruby theme={null} Appsignal.set_gauge("database_size", 100, :region => "eu") Appsignal.set_gauge("database_size", 50, :region => "us") Appsignal.set_gauge("database_size", 200, :region => "asia") # Multiple tags per metric Appsignal.set_gauge("my_metric_name", 100, :tag_a => "a", :tag_b => "b") Appsignal.set_gauge("my_metric_name", 10, :tag_a => "a", :tag_b => "b") Appsignal.set_gauge("my_metric_name", 200, :tag_a => "b", :tag_b => "c") ``` ```elixir Elixir theme={null} Appsignal.set_gauge("database_size", 100, %{region: "eu"}) Appsignal.set_gauge("database_size", 50, %{region: "us"}) Appsignal.set_gauge("database_size", 200, %{region: "asia"}) # Multiple tags per metric Appsignal.set_gauge("my_metric_name", 100, %{tag_a: "a", tag_b: "b"}) Appsignal.set_gauge("my_metric_name", 10, %{tag_a: "a", tag_b: "b"}) Appsignal.set_gauge("my_metric_name", 200, %{tag_a: "b", tag_b: "c"}) ``` ```javascript JavaScript theme={null} const meter = Appsignal.client.metrics(); meter.setGauge("database_size", 100, { region: "eu" }); meter.setGauge("database_size", 50, { region: "us" }); meter.setGauge("database_size", 200, { region: "asia" }); // Multiple tags per metric meter.setGauge("my_metric_name", 100, { tag_a: "a", tag_b: "b" }); meter.setGauge("my_metric_name", 10, { tag_a: "a", tag_b: "b" }); meter.setGauge("my_metric_name", 200, { tag_a: "b", tag_b: "c" }); ``` ```python Python theme={null} from appsignal import set_gauge set_gauge("database_size", 100, {"region": "eu"}) set_gauge("database_size", 50, {"region": "us"}) set_gauge("database_size", 200, {"region": "asia"}) # Multiple tags per metric set_gauge("my_metric_name", 100, {"tag_a": "a", "tag_b": "b"}) set_gauge("my_metric_name", 10, {"tag_a": "a", "tag_b": "b"}) set_gauge("my_metric_name", 200, {"tag_a": "b", "tag_b": "c"}) ``` ```php PHP theme={null} <?php use Appsignal\Appsignal; // Record gauge values with attributes (tags) Appsignal::setGauge('database_size', 100, ['region' => 'eu']); Appsignal::setGauge('database_size', 50, ['region' => 'us']); Appsignal::setGauge('database_size', 200, ['region' => 'asia']); // Multiple tags per metric Appsignal::setGauge('my_metric_name', 100, ['tag_a' => 'a', 'tag_b' => 'b']); Appsignal::setGauge('my_metric_name', 10, ['tag_a' => 'a', 'tag_b' => 'b']); Appsignal::setGauge('my_metric_name', 200, ['tag_a' => 'b', 'tag_b' => 'c']); ``` ```java Java theme={null} import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.metrics.DoubleGauge; import io.opentelemetry.api.metrics.Meter; public void recordTaggedMetrics() { Meter meter = GlobalOpenTelemetry.getMeter("my-app"); DoubleGauge gauge = meter.gaugeBuilder("database_size").build(); // Record gauge values with attributes (tags) gauge.set(100, Attributes.of( AttributeKey.stringKey("region"), "eu" )); gauge.set(50, Attributes.of( AttributeKey.stringKey("region"), "us" )); gauge.set(200, Attributes.of( AttributeKey.stringKey("region"), "asia" )); // Multiple tags per metric DoubleGauge myGauge = meter.gaugeBuilder("my_metric_name").build(); myGauge.set(100, Attributes.of( AttributeKey.stringKey("tag_a"), "a", AttributeKey.stringKey("tag_b"), "b" )); myGauge.set(10, Attributes.of( AttributeKey.stringKey("tag_a"), "a", AttributeKey.stringKey("tag_b"), "b" )); myGauge.set(200, Attributes.of( AttributeKey.stringKey("tag_a"), "b", AttributeKey.stringKey("tag_b"), "c" )); } ``` ```go Go theme={null} package main import ( "context" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/metric" ) func recordTaggedMetrics() { meter := otel.Meter("my-app") gauge, _ := meter.Float64Gauge("database_size") // Record gauge values with attributes (tags) gauge.Record(context.Background(), 100, metric.WithAttributes( attribute.String("region", "eu"), )) gauge.Record(context.Background(), 50, metric.WithAttributes( attribute.String("region", "us"), )) gauge.Record(context.Background(), 200, metric.WithAttributes( attribute.String("region", "asia"), )) // Multiple tags per metric myGauge, _ := meter.Float64Gauge("my_metric_name") myGauge.Record(context.Background(), 100, metric.WithAttributes( attribute.String("tag_a", "a"), attribute.String("tag_b", "b"), )) myGauge.Record(context.Background(), 10, metric.WithAttributes( attribute.String("tag_a", "a"), attribute.String("tag_b", "b"), )) myGauge.Record(context.Background(), 200, metric.WithAttributes( attribute.String("tag_a", "b"), attribute.String("tag_b", "c"), )) } ``` </CodeGroup> ## Rendering metric with and without tags If you created a custom metric and you have multiple tags associated with it, you can render the metric with and without the tag at the same time in a graph. <CodeGroup> ```ruby Ruby theme={null} Appsignal.increment_counter("sign_ups", 1, region: "eu") Appsignal.increment_counter("sign_ups", 1) ``` ```elixir Elixir theme={null} Appsignal.increment_counter("sign_ups", 1, %{region: "eu"}) Appsignal.increment_counter("sign_ups", 1) ``` ```javascript JavaScript theme={null} const meter = Appsignal.client.metrics(); meter.incrementCounter("sign_ups", 1, { region: "eu" }); meter.incrementCounter("sign_ups", 1); ``` ```python Python theme={null} from appsignal import increment_counter increment_counter("sign_ups", 1, {"region": "eu"}) increment_counter("sign_ups", 1) ``` ```php PHP theme={null} <?php use Appsignal\Appsignal; Appsignal::incrementCounter('sign_ups', 1, ['region' => 'eu']); Appsignal::incrementCounter('sign_ups', 1); ``` ```java Java theme={null} import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.metrics.LongCounter; import io.opentelemetry.api.metrics.Meter; public void recordMixedMetrics() { Meter meter = GlobalOpenTelemetry.getMeter("my-app"); LongCounter counter = meter.counterBuilder("sign_ups").build(); counter.add(1, Attributes.of( AttributeKey.stringKey("region"), "eu" )); counter.add(1); } ``` ```go Go theme={null} package main import ( "context" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/metric" ) func recordMixedMetrics() { meter := otel.Meter("my-app") counter, _ := meter.Int64Counter("sign_ups") counter.Add(context.Background(), 1, metric.WithAttributes( attribute.String("region", "eu"), )) counter.Add(context.Background(), 1) } ``` </CodeGroup> ## Graphing Custom Metrics Once you've started recording custom metrics, you can track them in custom graphs using the Graph Builder. Navigate to an existing dashboard or use the "Add dashboard" button in the Dashboard navigation to create a new one, then click "Add graph". <img alt="Graph Builder" /> When creating a graph, you can select which metrics and tags you want to chart and configure your graph's legends and labels. Once created, the graph will be added to the dashboard and display all recorded custom metric data for the specified period of time. You can read more about dashboards and graphs in our [Dashboard documentation](/metrics/dashboards). # Dashboards Source: https://docs.appsignal.com/metrics/dashboards This page provides more detailed information about how some dashboard charts options work. For all other options, please see the help icon with attached tooltip for more information. [Open the dashboard and chart builder](https://appsignal.com/redirect-to/app?to=dashboard\&overlay=dashboardForm) in your app. ## Charts types Some data is better understood if the chart is rendered in a different way. We provide the following display options: * Number chart * Line graph * Area graph * Relative area graph The number chart shows the value of a metric as a large number. This is useful for metrics that represent a single value, such as error count or request count. The number can represent the first or last value, the average, the sum, the minimum or maximum value over the selected time period. <img alt="Big Number Value chart example" /> When selecting the "Line graph", the default graph type is "Line graph". Use "Area graph" to render areas beneath the lines and "Relative area graph" to render a graph with the relative values of each data point. This will render a "percentage" of each data point from 0-100 and fill out the graph accordingly. This can be used to easily show the relation between data points in a graph. The image below shows the same metric in all three graph types. In the Line and Area graph you can see that the amount of data has increased, but the Relative area graph at the bottom shows that the relation between transmitted/received has not changed over time. <img alt="Graph display example" /> ## NULL values Not always does every point in time have a value for a metric, yet the value is not `0`. In our system we do not record a value for this time and treat this point as `NULL` rather than `0`. This means no value is present and can be interpreted in two ways. Either it was actually `0` or it retains the value of the last known data point in the graph. The "NULL values" option ("Draw NULL as 0" by default) allows for the configuration of the draw behavior for a graph. If set to "Draw NULL as 0" it will treat the `NULL` value as `0`. If set to "Repeat last known value" it will repeat the last known value until a later point in time specifies a new value. See the difference in the graph below. With "Draw NULL as 0" the graph makes a sharp drop to `0` every time the app stopped reporting data. With "Repeat last known value" the graph looks less volatile in terms of lines moving up and down. <img alt="Draw NULL as 0 option graph comparison screenshot" /> The app used to generate these graphs: <CodeGroup> ```ruby Ruby theme={null} # app.rb # gem install "appsignal" require "appsignal" Appsignal.configure("development") do |config| config.active = true config.name = "My app" config.push_api_key = "00000000-0000-0000-0000-000000000000" end Appsignal.start [ [5, 1], [7, 1], [3, 3], [5, 2], [2, 5], [10, 2], [8, 1], [4, 2] ].each do |(value, pause)| puts "set_gauge random_number #{value}" Appsignal.set_gauge("random_numbers", value) pause_in_minutes = pause * 60 puts "Sleeping #{pause} minute(s)" sleep pause_in_minutes end Appsignal.stop ``` </CodeGroup> # Host metrics Source: https://docs.appsignal.com/metrics/host-metrics The AppSignal agent collects various system metrics, which allows you to correlate performance issues and errors to abnormal host metrics. This data is available in the [Host metrics](https://appsignal.com/redirect-to/app?to=host_metrics) section in the app overview, which allows you to inspect and [compare multiple hosts](https://blog.appsignal.com/2018/02/20/comparing-hosts.html). We also show a host metrics overview on the sample detail page for error and performance incidents. For a preview of how host metrics look in the AppSignal interface, please see our [host metrics](https://www.appsignal.com/tour/hosts) tour page. <Tip> **Note**: This feature is available in these packages: * Ruby: gem version `1.2` and newer. Enabled by default since version `1.3`. * Elixir: package version `0.10.0` and newer. Enabled by default since version `0.10.0`. * Node.js: all package versions. * JavaScript for Front-end: none package versions. </Tip> <Tip> **Note**: This feature is not available on the following architectures: * macOS/OSX (`darwin`) * FreeBSD A list of supported Operating Systems is available on the [Supported Operating Systems](/support/operating-systems) page. </Tip> ## Collected host metrics The following host metrics are collected by the AppSignal agent for every minute on your system. | Metric | Description | | --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | CPU usage | User, nice, system, idle and iowait in percentages. <br />Read more about [CPU metrics](https://blog.appsignal.com/2018/03/06/understanding-cpu-statistics.html) Β in our academy article. | | Load average | 1 minute load average on the host. | | Memory usage | Available, free and used memory. Also includes swap total and swap used. | | Disk usage | Percentage of every disk used. | | Disk IO | Throughput of data read from and written to every disk. | | Network traffic | Throughput of data received and transmitted through every network interface. | These host metrics are collected by default. To disable it, use the `enable_host_metrics` configuration option, for: * [Ruby](/ruby/configuration/options#option-enable_host_metrics) * [Elixir](/elixir/configuration/options#option-enable_host_metrics) * [Node.js](/nodejs/3.x/configuration/options#option-enable_host_metrics) * [Python](/python/configuration/options#option-enable_host_metrics) * [Collector](/collector/configuration/options#option-enable_host_metrics) for [OpenTelemetry](/opentelemetry) * [Standalone agent](/standalone-agent/configuration/options#option-enable_host_metrics) ### Environment metadata The AppSignal agent reports the following information of the host. Once received this metadata is shown on the [host metrics index page](https://appsignal.com/redirect-to/app?to=host_metrics) per host to provide more detail of all hosts running an app. Use this metadata to spot any differences between hosts that could cause differences in behavior. * Host architecture, 32 or 64-bit. * Operating System, either Linux, macOS or Windows. * Operating System Distribution, for Linux this reports Ubuntu, Fedora, etc. * Operating System version, the version of the Operating System. * Kernel version, for Linux this reports the installed kernel version. This metadata is collected by default. To disable it, use the `send_environment_metadata` configuration option, for: * [Ruby](/ruby/configuration/options#option-send_environment_metadata) * [Elixir](/elixir/configuration/options#option-send_environment_metadata) * [Node.js](/nodejs/3.x/configuration/options#option-send_environment_metadata) * [Python](/python/configuration/options#option-send_environment_metadata) ## Heroku support To use host metrics on Heroku, head to the [Heroku host metrics][heroku support] page. ## Docker/container support To use host metrics on (Docker) containers, head to the [container host metrics](/metrics/host-metrics/containers) page. ## Dokku support <Tip> **Note**: Dokku support is available in packages Ruby gem 3.0.13, Elixir package 2.2.0, Node.js package 2.0.0 and newer. </Tip> [Dokku](https://github.com/dokku/dokku) has host metrics enabled by default as long as your Dokku application has the `DOKKU_ROOT` environment variable set up. [heroku support]: /heroku/host-metrics.html [container support]: /metrics/host-metrics/containers.html # Container host metrics Source: https://docs.appsignal.com/metrics/host-metrics/containers Host metrics for containerized systems are fully supported. <Warning> **Warning**: To get accurate metrics from your containers, container limits are required for your monitored containers. See the [container limits](#container-limits) section for more information. </Warning> <Tip> **Note**: While Heroku also runs on a containerized system (LXC), we do not support host metrics in the same way. Instead, please see the [Heroku support][heroku support] section. </Tip> <Tip> **Note**: This page is part of the [host metrics section](/metrics/host-metrics). </Tip> ## Container limits For container host metrics to be accurate, limits need to be set for every container. This means, configuring your container to have a limited number of CPUs and memory allocated to it. Without these limits the container reports the maximum possible value of these metrics, resulting in the host reporting Terabytes of available memory for example. A container without swap configured, or unsupported on the host system, will report a `0` value. For more information on how to limit your container's CPU and memory, please read the documentation on: * Docker * [CPU](https://docs.docker.com/config/containers/resource_constraints/#cpu) * [memory](https://docs.docker.com/config/containers/resource_constraints/#memory) * Kubernetes * [CPU](https://kubernetes.io/docs/tasks/configure-pod-container/assign-cpu-resource/) * [memory](https://kubernetes.io/docs/tasks/configure-pod-container/assign-memory-resource/) ## Supported metrics On systems that expose the `/sys/fs` virtual file system the following metrics are supported. | Metric | Description | | --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | CPU usage | User and system in percentages. <br /> Read more about [CPU metrics](https://blog.appsignal.com/2018/03/06/understanding-cpu-statistics.html) Β in our academy article. | | Load average | 1 minute load average on the host. | | Memory usage | Available, free and used memory. Also includes swap total and swap used. | | Disk usage | Percentage of every disk used. | | Disk IO | Throughput of data read from and written to every disk. | | Network traffic | Throughput of data received and transmitted through every network interface. | ### About CPU metrics In short: * AppSignal reports the same metrics as the [`docker stats`](https://docs.docker.com/engine/reference/commandline/stats/) command, but reported as an average on a minutely basis. * The reported CPU usage can go above 100%. 100% is equal to 1 full virtual CPU core. * [Container limits](#container-limits) are recommended to properly balance the available CPU resources between containers. * When multiple containers on the same host system share CPU resources, even with [container limits](#container-limits), containers that use more CPU can negatively impact the reported CPU usage for other containers. The container CPU metrics work a little differently than [normal CPU metrics](/metrics/host-metrics). They are affected by [container limits](#container-limits) and how many other containers are active on the system. This is because they share the container system's resources. Unlike normal host metrics the CPU usage can go above 100%. This is because a container can have more than 1 virtual CPU core available to it. Every full core amounts to 100%. If a container has three cores for example, the maximum is 300%. Other containers on the system can impact the total CPU time available to the container. [Limits](#container-limits) will help maintain a better balance of CPU usage between containers so the averages fluctuate less depending on busy neighbors. If all containers share all the host system's CPU resources, the usage on one host can negatively impact the available virtual CPU cores on another. For example: We have a Docker system on our host machine that has 3 virtual CPU cores available. We then start containers A, B and C without any specific CPU limits. * In the scenario of container A maxing out its available CPU cores, and the other containers B and C idling at 0%, it will be reported as 300% CPU usage for container A. Which is the total CPU time available on the host's container system. * When the three containers are all maxing out their available CPU cores it will be reported as 100% CPU usage for every container, as the resources are shared amongst them evenly. [heroku support]: /heroku/host-metrics.html # Magic dashboards Source: https://docs.appsignal.com/metrics/magic-dashboards AppSignal automatically creates dashboards when it detects metrics from a supported integration. These magic dashboards give you pre-built charts for the most important metrics of each integration, without any manual setup. Magic dashboards appear in the **Dashboards** section of your app, labeled as **Automated**. They are created the first time AppSignal receives metrics from a supported source. If you remove the integration or stop sending the metrics, the dashboard stays in place so you can reference historical data. ## How magic dashboards work Each integration sends specific metrics to AppSignal. When AppSignal recognizes a set of metrics that matches a known integration, it creates a dashboard with charts tailored to that integration. The charts, layout, and descriptions are maintained by AppSignal and updated automatically unless you have customized the dashboard. Dashboards are designed to answer common operational questions quickly. Health and error indicators appear first, followed by resource utilization, then operational context. Chart descriptions explain what values indicate a problem and what to do about it. ## Available magic dashboards Magic dashboards are available for the following integrations, grouped by category. Each link leads to the integration's setup instructions and dashboard details. ### AWS CloudWatch AppSignal supports magic dashboards for over 46 AWS services through [CloudWatch Metric Streams](/metrics/cloudwatch-overview). Each AWS service gets its own dashboard with charts ordered by urgency of signal. See [AWS magic dashboards](/metrics/aws-dashboards) for the full list of supported services and their charts. ### Ruby The following integrations create magic dashboards when AppSignal detects their metrics in a Ruby app: * [Active Job](/ruby/integrations/active-job#magic-dashboard) β€” job duration, job status per queue, and throughput per job class. * [Sidekiq](/ruby/integrations/sidekiq#magic-dashboard) β€” worker duration, queue latency, queue length, job status, Redis memory usage, and connection counts. * [Puma](/ruby/integrations/puma#magic-dashboard) β€” thread pool capacity, connection backlog, and worker status. * [MongoDB](/ruby/integrations/mongodb#magic-dashboard) β€” query throughput and query duration per database. * [Ruby VM](/ruby/integrations/ruby-vm#magic-dashboards) β€” garbage collection counts, heap slots, allocated objects, and thread count. * [Global VM Lock](/ruby/integrations/global-vm-lock#magic-dashboards) β€” GVL wait time and waiting thread count. * Action Mailer β€” deliveries per mailer action. * Karafka β€” consumer messages, batches, lag, errors, connections, and thread counts. ### Elixir * [Oban](/elixir/integrations/oban) β€” job duration, queue wait time, and job counts broken down by worker, queue, and status. * [Erlang VM](/elixir/integrations/erlang) β€” I/O, schedulers, processes, memory, atoms, and scheduler utilization. ### Node.js * [V8 heap statistics](/nodejs/3.x/integrations/core) β€” heap size, used heap, malloced memory, and native context counts. ### General * Process Memory β€” RSS memory usage per host and process type. Available for Ruby and Elixir apps. ### Infrastructure * [NGINX](/metrics/nginx#magic-dashboard) β€” request time, throughput, status codes, connections, and upstream proxy metrics. * [Kubernetes](/metrics/kubernetes-0.x) β€” node and pod resource usage including CPU, memory, swap, disk, and network, across two dashboards (nodes and pods). ### Heroku Heroku creates several magic dashboards from Log Drain or Telemetry Drain data: * [Status codes](/heroku/dashboards#status-code-dashboard) β€” HTTP status code breakdown (Cedar generation only). * [Redis](/heroku/dashboards#redis-dashboard) β€” connections, hit rate, evictions, memory, and I/O. * [PostgreSQL](/heroku/dashboards#postgresql-dashboard) β€” connections, cache hit rate, memory, load average, and I/O (Standard and Premium plans). ### Vector AppSignal creates dashboards from metrics collected through [Vector](/vector) sources: * [PostgreSQL](/vector/postgresql) β€” record operations, transactions, deadlocks, and temporary file writes. * [MongoDB](/vector/mongodb) β€” three dashboards covering status (memory, connections, operations), WiredTiger storage engine internals, and replication health. ### Vercel * [Speed Insights](/vercel/speed-insights) β€” Next.js Web Vitals for real-user performance monitoring. # NGINX metrics Source: https://docs.appsignal.com/metrics/nginx The AppSignal integrations and the AppSignal stand-alone agent can generate metrics from your NGINX server's access logs. After configuring your NGINX server to send metrics to AppSignal, a magic dashboard with metrics related to your NGINX server will appear. ## Configuring AppSignal First, you must configure your AppSignal integration or stand-alone agent to receive metrics from NGINX. <Tip> Enabling NGINX metrics will open a server for NGINX to send metrics to. By default, this server is bound to `localhost` and listens on port `27649`. You can modify these settings using the `bind_address` and `nginx_port` configuration options. If you are running several AppSignal-instrumented applications at a time in the same server, you can configure each application to listen on a different port using the `nginx_port` configuration option. </Tip> If you configure your AppSignal integration with environment variables, you must set `APPSIGNAL_ENABLE_NGINX_METRICS` to true. If you configure your AppSignal integration with configuration files, or you use the stand-alone agent, you can follow the relevant instructions below on how to enable NGINX metrics for your application: * [Ruby configuration](#ruby) * [Elixir configuration](#elixir) * [Node.js configuration](#nodejs) * [Stand-alone Agent configuration](#standalone-agent) ### Ruby <Tip> Support for NGINX metrics was added in version `3.3.4` of the Ruby integration. </Tip> Add `enable_nginx_metrics: true` to the desired environment in your application's`config/appsignal.yml` file, for example the production environment: <CodeGroup> ```yaml YAML theme={null} production: enable_nginx_metrics: true # ... ``` </CodeGroup> ### Elixir <Tip> Support for NGINX metrics was added in version `2.5.2` of the Elixir integration. </Tip> Add `enable_nginx_metrics: true` to your AppSignal configuration block, usually located at `config/config.exs`: <CodeGroup> ```elixir Elixir theme={null} config :appsignal, :config, enable_nginx_metrics: true, # ... ``` </CodeGroup> ### Node.js <Tip> Support for NGINX metrics was added in version `3.0.8` of the Node.js integration. </Tip> Add `enableNginxMetrics: true` to your `appsignal.cjs` file: <CodeGroup> ```javascript Node.js theme={null} new Appsignal({ enableNginxMetrics: true, // ... }); ``` </CodeGroup> ### Stand-alone agent <Tip> Support for NGINX metrics was added in version `0.0.24` of the stand-alone agent. </Tip> Add `enable_nginx_metrics = true` to your `/etc/appsignal-agent.conf` configuration file: <CodeGroup> ```toml TOML theme={null} enable_nginx_metrics = true ``` </CodeGroup> ## Configuring NGINX The next step is configuring your NGINX server to send metrics to AppSignal. In most Linux distributions, the default NGINX configuration will include configuration files from a configuration folder, often located in `/etc/nginx/conf.d`. Save the following configuration to that folder as `appsignal-metrics.conf`: <CodeGroup> ```nginx NGINX theme={null} map '' $appsignal_group { default 'http'; } log_format appsignal_metrics '1|g=$appsignal_group;s=$status;rqt=$request_time;rql=$request_length;bs=$bytes_sent;ua=$upstream_addr;uct=$upstream_connect_time;uht=$upstream_header_time;urst=$upstream_response_time;us=$upstream_status;ucs=$upstream_cache_status;ca=$connections_active;cr=$connections_reading;cwr=$connections_writing;cwa=$connections_waiting'; access_log syslog:server=127.0.0.1:27649,tag=appsignal_nginx appsignal_metrics; ``` </CodeGroup> <Note> Replace `127.0.0.1:27649` with the host and port where your AppSignal integration or stand-alone agent is listening for NGINX metrics. </Note> If your NGINX configuration does not include configuration files as described above, you can include it yourself from within the `http` block of your `nginx.conf` file: <CodeGroup> ```nginx NGINX theme={null} http { include '/path/to/appsignal-metrics.conf'; ... } ``` </CodeGroup> Note that if a `server` or `location` block contains an `access_log` directive, metrics for requests to that server or location will not be reported to AppSignal. To report metrics to AppSignal for those requests, you will need to add the following line inside the block: ```sh Shell theme={null} access_log syslog:server=127.0.0.1:27649,tag=appsignal_nginx appsignal_metrics; ``` <Note> Replace `127.0.0.1:27649` with the host and port where your AppSignal integration or stand-alone agent is listening for NGINX metrics. </Note> The existing `access_log` directive inside the block will continue to work as before. ### Configuring request groups By changing the value of the `$appsignal_group` variable within a `location` or `server` block in your NGINX configuration, you can differentiate between different kinds of requests handled by your NGINX server: <CodeGroup> ```nginx NGINX theme={null} location /admin { set $appsignal_group 'admin'; ... } ``` </CodeGroup> Metrics related to requests will be segmented by their group, and the different groups will be tracked independently in the magic dashboard graphs for those metrics. ### Disabling metrics You can use the `access_log off` directive to disable all access logs within a `location` or `server` block. Note that this will disable *all* access logs configured, not just those that are sent to AppSignal as metrics. To only report metrics from specific `location` or `server` blocks, remove the following line from the `appsignal-metrics.conf` file, then add it only inside the specific `location` or `server` blocks that you would like to report metrics to AppSignal from: <CodeGroup> ```nginx NGINX theme={null} access_log syslog:server=127.0.0.1:27649,tag=appsignal_nginx appsignal_metrics; ``` </CodeGroup> <Note> Replace `127.0.0.1:27649` with the host and port where your AppSignal integration or stand-alone agent is listening for NGINX metrics. </Note> Doing this will implicitly disable all access logs from `access_log` directives in the surrounding `server` or `http` block. To enable those access logs again, repeat their corresponding `access_log` directive inside the `location` or `server` block that you added the above line to: <CodeGroup> ```nginx NGINX theme={null} server { access_log /var/log/nginx/access.log main; location /app { # this line enables AppSignal NGINX metrics for this location # but it also disables the access log declared in the server block access_log syslog:server=127.0.0.1:27649,tag=appsignal_nginx appsignal_metrics; # this line enables the access log declared in the server block again access_log /var/log/nginx/access.log main; } } ``` </CodeGroup> ## Magic dashboard <img alt="The NGINX magic dashboard" /> The [metrics sent to AppSignal by your NGINX server](#metrics) will be used to create a magic dashboard. In this dashboard, you will be able to see graphs representing useful metrics over time, such as: * **Request time:** the time taken by your NGINX server to respond to a request, as a per-minute mean and 95th percentile. * **Throughput:** a count of the requests handled by your NGINX server. * **Request length:** the length in bytes of the request received from the client by your NGINX server, as a per-minute mean and 95th percentile. * **Response length:** the length in bytes of the response sent to the client by your NGINX server, as a per-minute mean and 95th percentile. * **Status codes:** a count of the status codes of the responses sent by your NGINX server. * **Connections:** a gauge of the connections currently being handled by your NGINX server, measured once per minute and segmented by the status of the connection. * **Upstream status codes:** a count of the status codes of the responses sent by the upstream servers that your NGINX server proxies from. * **Upstream response time:** the time taken to respond to a request by the upstream servers that your NGINX server proxies from, as a per-minute mean and 95th percentile. * **Upstream cache status:** the status of the cache (such as `HIT` or `MISS`) when handling a cached request proxied from an upstream server. Most of these graphs are segmented by [the request group](#configuring-request-groups), the hostname or the relevant upstream, if any. You can, however, dive in to the graph editor and pick a different segmentation that provides a more useful view into your data. See the section below for a detailed breakdown of the metrics sent from your NGINX server. ## Metrics The following metrics will be sent to AppSignal from your NGINX server: * **`nginx_status`**: A counter incrementing for each request handled by your NGINX server. Tagged by: * `status`: The status code of the response. * `group`: The request group, as [configured in your NGINX server](#configuring-request-groups). * `hostname`: The hostname of the server that handled the request. * **`nginx_request_time`**: A distribution of the time taken to respond to each request. Tagged by: * **`group`**: The request group, as [configured in your NGINX server](#configuring-request-groups). * **`hostname`**: The hostname of the server that handled the request. * `nginx_request_length`: A distribution of the bytes received in the request from the client, for each request. Tagged by: * **`group`**: The request group, as [configured in your NGINX server](#configuring-request-groups). * **`hostname`**: The hostname of the server that handled the request. * `nginx_bytes_sent`: A distribution of the bytes sent in the response to the client, for each request. Tagged by: * **`group`**: The request group, as [configured in your NGINX server](#configuring-request-groups). * **`hostname`**: The hostname of the server that handled the request. If the request is handled by proxying from an upstream using the `proxy_pass` NGINX directive, the following metrics will also be present: * `nginx_upstream_time`: A distribution of the time it took to communicate with the upstream server. Tagged by: * **`group`**: The request group, as [configured in your NGINX server](#configuring-request-groups). * **`hostname`**: The hostname of the server that handled the request. * **`upstream`**: The upstream server that the request was proxied to. * **`measurement`**: The specific time measured: * `connect`: The time it took for the connection to be established. * `header`: The time it took for the response header to be sent. * `response`: The time it took for the full response to be sent. * `nginx_upstream_status`: A counter incrementing for each request proxied to an upstream. Tagged by: * **`status`**: The status code of the response. * **`group`**: The request group, as [configured in your NGINX server](#configuring-request-groups). * **`hostname`**: The hostname of the server that handled the request. * **`upstream`**: The upstream server that the request was proxied to. If the request proxied from an upstream is cached using the `proxy_cache` NGINX directive, the following metric will also be present: * `nginx_upstream_cache_status`: A counter incrementing for each request proxied to an upstream with caching enabled. Tagged by: * **`status`**: The [cache status](http://nginx.org/en/docs/http/ngx_http_upstream_module.html#var_upstream_cache_status) for the request. * **`group`**: The request group, as [configured in your NGINX server](#configuring-request-groups). * **`hostname`**: The hostname of the server that handled the request. If your NGINX server has been built with the `ngx_http_stub_status_module` NGINX module enabled (as provided by most Linux distributions) then the following metric will also be present: * `nginx_connections`: The number of connections that your NGINX server is currently handling. Tagged by: * **`hostname`**: The hostname of the server that handled the request. * **`measurement`**: The specific number of connections measured: * `active`: The number of active connections. * `reading`: The number of connections where the request is being read. * `writing`: The number of connections where the response is being written. * `waiting`: The number of idle connections. The connections metric always refers to the hostname as a whole, not to a specific group. Its value is updated once per minute. <Tip> The server hostname used for the metrics is not the NGINX hostname value, but the hostname value configured for the AppSignal integration or standalone agent. This value is usually configured automatically, and can be overriden by the `hostname` configuration option. </Tip> ## Support If you are experiencing any difficulties configuring your application's NGINX metrics, [contact support](mailto:support@appsignal.com), and we'll help you get your metrics flowing. # AppSignal for Node.js Source: https://docs.appsignal.com/nodejs/3.x AppSignal for [Node.js](https://nodejs.org/en/) helps you get the most out of your Node.js application, providing you with the tools you need to track errors and monitor the performance of your application's code. The package supports pure JavaScript and TypeScript applications and can auto-instrument various frameworks and packages with optional plugins. Other frameworks and packages might require some [custom instrumentation](/nodejs/3.x/instrumentation). ## OpenTelemetry OpenTelemetry is an open-source project that facilitates the instrumentation of standardized telemetry data collection. This means that you can easily integrate your data with AppSignal or another vendor of your choice. You're not locked into a single provider's services. As OpenTelemetry is an open-source project, everyone can collaborate on the same base integrations to provide instrumentation for the benefit of everyone. OpenTelemetry currently supports several popular programming languages, including Node.js. OpenTelemetry consists of multiple components: tracing, metrics, and logs. These components are still a work in progress in most programming languages, with tracing for many languages being the most stable component. We support OpenTelemetry's tracing component in our Node.js integration to provide better error reporting and performance measurements. **[Learn more about OpenTelemetry via the project's official website.](https://opentelemetry.io/)** ## Supported Libraries Our integration supports the following libraries and frameworks: * [Node.js Core](/nodejs/3.x/integrations/core) * [Apollo Gateway](/nodejs/3.x/integrations/apollo-gateway) * [BullMQ](/nodejs/3.x/integrations/bullmq) * [Elasticsearch](/nodejs/3.x/integrations/elasticsearch) * [Express](/nodejs/3.x/integrations/express) * [Fastify](/nodejs/3.x/integrations/fastify) * [GraphQL (such as Apollo Server or Yoga)](/nodejs/3.x/integrations/graphql) * [Knex.js](/nodejs/3.x/integrations/knexjs) * [Koa.js](/nodejs/3.x/integrations/koajs) * [MongoDB](/nodejs/3.x/integrations/mongo) * [Mongoose](/nodejs/3.x/integrations/mongoose) * [MySQL (mysql and mysql2 packages)](/nodejs/3.x/integrations/mysql) * [NestJS](/nodejs/3.x/integrations/nestjs) * [Next.js](/nodejs/3.x/integrations/nextjs) * [PostgreSQL](/nodejs/3.x/integrations/pg) * [Prisma](/nodejs/3.x/integrations/prisma) * [Redis (redis and ioredis packages)](/nodejs/3.x/integrations/redis) * [Remix](/nodejs/3.x/integrations/remix) * [Restify](/nodejs/3.x/integrations/restify) ## Supported Environments <Note> πŸ”§ Support for Node.js is defined on our [maintenance policy page](/support/maintenance-policy). </Note> Node.js is an incredibly flexible runtime, which allows it to be used for a multiple of different use-cases. AppSignal was primarily designed for use on a server, so there are a few places that the Node.js integration is currently not suitable: * **Electron apps:** We don't recommend using @appsignal/nodejs inside [Electron](https://www.electronjs.org/) applications. As we designed the [agent](/appsignal/terminology#agent) to run on a server, it is not currently useful in this environment. It will also lead to possibly unwanted complexity around cross-compilation of the native extension. * **Short-lived processes:** Short-lived processes, such as CLI tools, are a poor fit for the agent, which must be able to stay running for a period of time (at least 60 seconds). * **Serverless functions:** Serverless functions are meant to be short-lived processes, so they are also a poor fit for the agent. * **Statically generated apps:** Some environments (e.g [Gatsby.js](https://www.gatsbyjs.com/), [Svelte](https://svelte.dev/)) offer some access to Node.js APIs but ultimately compile their code down to a client side application, and therefore aren't suitable for the Node.js library. ***Don't panic!*** The [@appsignal/javascript library](/front-end/) does not require the agent and will work where @appsignal/nodejs doesn't currently work, however only error tracking is supported at the moment. # Bundling with esbuild Source: https://docs.appsignal.com/nodejs/3.x/bundling-with-esbuild If you're bundling your Node.js app with [esbuild](https://esbuild.github.io/), it's necessary to mark the packages to instrument as external. For example, if you are running an application with Mongoose and you want to send instrumentation data to AppSignal, you must flag the Mongoose dependency as `external` in your build script command as in the example below: <CodeGroup> ```json JSON theme={null} { //... "build:appsignal": "esbuild src/appsignal.ts --bundle --platform=node --external:mongoose --external:@appsignal/nodejs" //... } ``` </CodeGroup> # AppSignal for Node.js: Command line tools Source: https://docs.appsignal.com/nodejs/3.x/command-line The optional [`@appsignal/cli` package][package] includes several command-line tools. These tools make it easier to install AppSignal in an application, send deploy notifications and diagnose any problems with the installation. ## Diagnose A self-diagnostic tool for the AppSignal for nodejs gem. This tool can be used to debug your AppSignal installation and is one of the first things our support team asks for when there's an issue. Read more about the [`npx @appsignal/cli diagnose`][cli-diagnose] command line tool. [package]: https://github.com/appsignal/appsignal-nodejs [cli-diagnose]: /nodejs/3.x/command-line/diagnose.html [cli-demo]: /nodejs/3.x/command-line/demo.html # AppSignal for Node.js: Demonstration tool Source: https://docs.appsignal.com/nodejs/3.x/command-line/demo The AppSignal for Node.js package ships with a command line tool used to send demonstration samples to AppSignal. Upon running it, it sends an error and performance sample to AppSignal from the user's machine. This command line tool is useful when testing AppSignal on a system and validating the local configuration. It tests if the installation of AppSignal has succeeded and if the AppSignal agent is able to run on the machine's architecture and communicate with the AppSignal servers. Read more about how to use the demonstration command on the [Debugging][debugging] page. ## Usage On the command line in your project run: <CodeGroup> ```bash Bash theme={null} npx @appsignal/cli demo ``` </CodeGroup> To run it with a specific environment, Push API key or application name, see the [CLI options](#options). <CodeGroup> ```bash Bash theme={null} npx @appsignal/cli demo --environment=production --api-key="<PUSH API KEY HERE>" --application="My app" ``` </CodeGroup> ## Options | Option | Description | | ----------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `--api-key=<key>` | Specify the Push API Key to use for the app. [Config option `pushApiKey`](/nodejs/3.x/configuration/options#option-pushapikey). | | `--application=<key>` | The name of the app to send the demo samples for. [Config option `name`](/nodejs/3.x/configuration/options#option-name). | | `--environment=<environment>` | Set the environment to use in the command, e.g. `production` or `staging`. [Config option `environment`](/nodejs/3.x/configuration/options#option-environment). | If no options are specified the demo tool will use the [environment variables of config options](/nodejs/3.x/configuration/options) if present. [debugging]: /support/debugging.html # AppSignal for Node.js: Diagnose tool Source: https://docs.appsignal.com/nodejs/3.x/command-line/diagnose The AppSignal Node.js package ships with a self-diagnostic tool. This tool can be used to debug your AppSignal installation and is one of the first things our support team asks for when there's an issue. ## The diagnostic report This command-line tool is useful when testing AppSignal on a system and validating the local configuration. It outputs useful information to debug issues and it checks if AppSignal agent can run on the machine's architecture and communicate with the AppSignal servers. This diagnostic tool collects and outputs the following: * information about the AppSignal package. * information about the host system and Node.js. * if the AppSignal [extension](/appsignal/how-appsignal-operates#extension) and [agent](/appsignal/how-appsignal-operates#agent) can run on the host system. * all configured config options (including default values). * if the configuration is valid and active. * if the Push API key is present and valid (internet connection required). * where configuration option values originate from. Read more about how to use the diagnose command on the [Debugging][debugging] page. ## Submitting the report You need to pass the `--send-report` option to send the diagnose report to AppSignal. If used, the report will be send to our servers and you will receive a support token. When you [send this support token to us](mailto:support@appsignal.com) we will review the report and help you debug the issue. We've seen that copy-pasting the report output usually loses formatting and makes it harder to read, which is why it's sent to our servers in the JSON format. ## Usage On the command line in your project (a directory with a `package.json` and `@appsignal/nodejs` installed) run: <CodeGroup> ```bash Bash theme={null} npx @appsignal/cli diagnose ``` </CodeGroup> At the very least, the `APPSIGNAL_PUSH_API_KEY` must be set before the diagnose command can be run. If this isn't set in your environment already, you can also set it at runtime with the `--api-key` option: <CodeGroup> ```bash Bash theme={null} npx @appsignal/cli diagnose --api-key="<PUSH API KEY HERE>" ``` </CodeGroup> You can also set the environment variable at runtime: <CodeGroup> ```bash Bash theme={null} APPSIGNAL_PUSH_API_KEY="<PUSH API KEY HERE>" npx @appsignal/cli diagnose ``` </CodeGroup> To run the diagnose on your production server, and send the report to AppSignal for support purposes, you can run the following command: <CodeGroup> ```bash Bash theme={null} npx @appsignal/cli diagnose --environment=production --send-report --api-key="<PUSH API KEY HERE>" ``` </CodeGroup> The environment option is useful when the default environment is not the one you want to diagnose. The diagnose tool will warn you when no environment is selected. ## Options | Option | Description | | ---------------------------------------------------- | -------------------------------------------------------------------------- | | [`--environment=<environment>`](#environment-option) | Set the environment to use in the command, e.g. `production` or `staging`. | | `--api-key` | Define which API key to use. | | [`--[no-]send-report`](#report-submission-option) | Automatically send, or do not send the report. | ### Environment option Define which app environment AppSignal should load in the diagnose CLI. <CodeGroup> ```bash Bash theme={null} npx @appsignal/cli diagnose --environment=production ``` </CodeGroup> ### Report submission option The options to [submit the report](#submitting-the-report) immediately, or not, were added to the AppSignal Node.js package version `1.2.5`. Submit the report to AppSignal: <CodeGroup> ```bash Bash theme={null} npx @appsignal/cli diagnose --send-report ``` </CodeGroup> Do not submit the report to AppSignal: <CodeGroup> ```bash Bash theme={null} npx @appsignal/cli diagnose --no-send-report ``` </CodeGroup> ## Configuration output format ### Configuration option values format The configuration options are printed to the CLI as their inspected values. This means we print them as Node.js would in a console. * Strings values are printed with double quotes around them, e.g. `"My app name"`. * Booleans values are printed as their raw values: `true` and `false`. * Arrays values are printed as a collection of values surrounded by square brackets, e.g. `["HTTP_ACCEPT", "HTTP_ACCEPT_CHARSET"]`. * Empty Arrays are printed as two square brackets: `[]`. * Null or undefined values are printed as `null` or `undefined`. [debugging]: /support/debugging.html # AppSignal for Node.js configuration Source: https://docs.appsignal.com/nodejs/3.x/configuration In this section, we'll explain how to configure AppSignal, what can be configured in the Node.js package, and what the minimal configuration needed is. ## Minimal required configuration The minimal required configuration needed by AppSignal for Node.js is the following items. If they are not present, AppSignal will not send any data to AppSignal.com. * A valid Push API Key * An application name * An application environment (`development`/`production`/`test` by setting `NODE_ENV`) * The setting `active: true` The integration supports loading its configuration via options passed to the `Appsignal` constructor. We recommend creating an `appsignal.cjs` file to require and initialize AppSignal. <CodeGroup> ```javascript Node.js theme={null} // appsignal.cjs const { Appsignal } = require("@appsignal/nodejs"); new Appsignal({ active: true, name: "<YOUR APPLICATION NAME>", pushApiKey: "<YOUR API KEY>", }); ``` </CodeGroup> Alternatively, you can configure the agent using system environment variables. AppSignal will automatically become active if the `APPSIGNAL_PUSH_API_KEY` environment variable is set. <CodeGroup> ```bash Bash theme={null} export APPSIGNAL_PUSH_API_KEY="<YOUR API KEY>" export APPSIGNAL_APP_NAME="<YOUR APPLICATION NAME>" export APPSIGNAL_APP_ENV="production" ``` </CodeGroup> ## Configuration options Read about all the configuration options on the [options page](/nodejs/3.x/configuration/options). ## Application environments An application can have multiple environments such as "development", "test", "staging" and "production". To separate the errors and performance issues that occur in the "development" environment and those in "production", it's possible to set the environment in which the application is running with the `NODE_ENV` environment variable. If you activate AppSignal per environment, you can set the `active` property of the options you pass into the constructor conditionally: <CodeGroup> ```javascript Node.js theme={null} // appsignal.cjs const { Appsignal } = require("@appsignal/nodejs"); new Appsignal({ active: process.env.NODE_ENV !== "development", name: "<YOUR APPLICATION NAME>", pushApiKey: "<YOUR API KEY>", }); ``` </CodeGroup> This will also disable AppSignal when running your tests. # AppSignal for Node.js load order Source: https://docs.appsignal.com/nodejs/3.x/configuration/load-order AppSignal for Node.js can be configured in a couple of different ways - through the `Appsignal` constructor or environment variables. The configuration is loaded in a four-step process, starting with the package defaults and ending with reading environment variables. The configuration options can be mixed without losing configuration from a different option. ## Load orders * 1. [Package defaults - `default`](#1-module-defaults) * 2. [System detected settings - `system`](#2-system-detected-settings) * 3. [Environment variables - `env`](#3-environment-variables) * 4. [`Appsignal` constructor - `initial`](#4-initial-configuration-given-to-appsignal-constructor) ## 1. Module defaults The AppSignal module starts with loading its default configuration, setting paths and enabling certain features. The agent defaults can be found in the [configuration options documentation](/nodejs/3.x/configuration/options). ## 2. System detected settings The package detects what kind of system it's running on and configures itself accordingly. For example, when it's running inside a container-based system (such as Docker and Heroku) it sets the configuration option `runningInContainer` to `true`. ## 3. Environment variables AppSignal will look for its configuration in environment variables. When found these will override all given configuration options from previous steps. <CodeGroup> ```bash Bash theme={null} export APPSIGNAL_APP_NAME="my custom app name" # start your app here ``` </CodeGroup> ## 4. Initial configuration given to `Appsignal` constructor When initializing the `Appsignal` object, you can pass in the initial configuration you want to apply. This is an `object` of any of the options described below. <CodeGroup> ```javascript Node.js theme={null} new Appsignal({ active: true, name: "<YOUR APPLICATION NAME>", pushApiKey: "<YOUR API KEY>", }); ``` </CodeGroup> This step will override all given options from the defaults or system detected configuration. # Node.js package configuration options Source: https://docs.appsignal.com/nodejs/3.x/configuration/options The following list includes all configuration options with the name of the environment variable and the name of the key in the configuration file. For more information on how to configure AppSignal with a configuration file or system environment variables, see our [Configuration](/nodejs/3.x/configuration) topic. ## Available options * Required options * [`active`](#option-active) * [`environment`](#option-environment) * [`name`](#option-name) * [`pushApiKey`](#option-pushapikey) * Options * [`additionalInstrumentations`](#option-additionalinstrumentations) * [`bindAddress`](#option-bindaddress) * [`caFilePath`](#option-cafilepath) * [`cpuCount`](#option-cpucount) * [`debug`](#option-debug) * [`disableDefaultInstrumentations`](#option-disabledefaultinstrumentations) * [`dnsServers`](#option-dnsservers) * [`enableHostMetrics`](#option-enablehostmetrics) * [`enableMinutelyProbes`](#option-enableminutelyprobes) * [`enableNginxMetrics`](#option-enablenginxmetrics) * [`enableOpentelemetryHttp`](#option-enableopentelemetryhttp) * [`enableStatsd`](#option-enablestatsd) * [`filesWorldAccessible`](#option-filesworldaccessible) * [`filterParameters`](#option-filterparameters) * [`filterSessionData`](#option-filtersessiondata) * [`hostname`](#option-hostname) * [`hostRole`](#option-hostrole) * [`httpProxy`](#option-httpproxy) * [`ignoreActions`](#option-ignoreactions) * [`ignoreErrors`](#option-ignoreerrors) * [`ignoreLogs`](#option-ignorelogs) * [`ignoreNamespaces`](#option-ignorenamespaces) * [`log`](#option-log) * [`logLevel`](#option-loglevel) * [`logPath`](#option-logpath) * [`nginxPort`](#option-nginxport) * [`opentelemetry_port`](#option-opentelemetry_port) * [`requestHeaders`](#option-requestheaders) * [`revision`](#option-revision) * [`runningInContainer`](#option-runningincontainer) * [`sendEnvironmentMetadata`](#option-sendenvironmentmetadata) * [`sendParams`](#option-sendparams) * [`sendSessionData`](#option-sendsessiondata) * [`statsdPort`](#option-statsdport) * [`workingDirectoryPath`](#option-workingdirectorypath) ## active <a /> | Field | Value | | ---------------------- | -------------------------- | | Config file key | `active` | | System environment key | `APPSIGNAL_ACTIVE` | | Required | yes | | Type | Boolean (`true` / `false`) | | Default value | `false` | ### Description Configure AppSignal to be active or not for a given environment. Most commonly used in the [file configuration](/nodejs/3.x/configuration) per environment. ## environment <a /> | Field | Value | | ---------------------- | ------------------------------------------------------------------------ | | Config file key | `environment` | | System environment key | `APPSIGNAL_APP_ENV` | | Required | yes | | Type | `String` | | Default value | `Read from environment variable `NODE\_ENV`, defaults to "development".` | ### Description The environment of the app to be reported to AppSignal. <Note> **Note**: Changing the [name](#option-name) or environment of an existing app will create a new app on AppSignal.com. </Note> ## name <a /> | Field | Value | | ---------------------- | -------------------- | | Config file key | `name` | | System environment key | `APPSIGNAL_APP_NAME` | | Required | yes | | Type | `String` | | Default value | `nil` | ### Description Name of your application as it should be displayed on AppSignal.com. <Note> **Note**: Changing the name or [environment](#option-env) of an existing app will create a new app on AppSignal.com. </Note> ## pushApiKey <a /> | Field | Value | | ----------------------- | -------------------------------------------------------------------------------- | | Config file key | `pushApiKey` | | System environment key | `APPSIGNAL_PUSH_API_KEY` | | Required | yes | | Type | `String` | | Default value | `null` (unset by default) | | Available since version | `2.2.5` | | | <ul><li>This config option was renamed from `apiKey` in version 2.2.5.</li></ul> | ### Description The organization-level authentication key to authenticate with our Push API. Read more about the [AppSignal Push API key](/appsignal/terminology#push-api-key). ## additionalInstrumentations <a /> | Field | Value | | ----------------------- | ---------------------------- | | Config file key | `additionalInstrumentations` | | Required | no | | Type | `list(String)` | | Default value | `[]` | | Available since version | `3.0.0` | ### Description List of additional OpenTelemetry instrumentations to use with AppSignal, via third-party libraries or your own integrations. ## bindAddress <a /> | Field | Value | | ----------------------- | ------------------------ | | Config file key | `bindAddress` | | System environment key | `APPSIGNAL_BIND_ADDRESS` | | Required | no | | Type | `String` | | Default value | `127.0.0.1` | | Available since version | `3.0.15` | ### Description A valid IPv4 address the AppSignal agent uses as a binding for its TCP and UDP servers. Use a specific address if you only want the agent to listen to requests made to that address. Set this option to `0.0.0.0` to allow to receive requests from hosts using any IP address. By default it only listens to requests made on the same host. This option is applied to all the agent servers ([StatsD](#option-enable_statsd), [OpenTelemetry](#option-enable_opentelemetry_http) and [NGINX](#option-enable_nginx_metrics)). ## caFilePath <a /> | Field | Value | | ---------------------- | -------------------------------- | | Config file key | `caFilePath` | | System environment key | `APPSIGNAL_CA_FILE_PATH` | | Required | no | | Type | `String` | | Default value | Packaged `cacert.pem` file path. | ### Description Use this option to point to another certificate file if there's a problem connecting to our API. <Note> **Note**: The specified path cannot contain Operating Specific file system abstractions, such as the homedir symbol `~` for \*NIX systems. This will be seen as a malformed path. </Note> ## cpuCount <a /> | Field | Value | | ----------------------- | --------------------- | | Config file key | `cpuCount` | | System environment key | `APPSIGNAL_CPU_COUNT` | | Required | no | | Type | `Float` | | Default value | `undefined` | | Available since version | `3.3.2` | ### Description The available CPU capacity of the host, in number of CPUs. This is used to calculate the CPU usage percentage in the host metrics. If not set, the agent will attempt to automatically detect this from cgroups. The number of CPUs can be a fraction, e.g. `0.5`. ## debug <a /> | Field | Value | | ----------------------- | --------------------------------------------------------------------------------------------------------------- | | Config file key | `debug` | | System environment key | `APPSIGNAL_DEBUG` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `false` | | Available since version | `1.0.0` | | | <ul><li>Deprecated since version 2.2.6 in favor of the [`log_level` config option](#option-loglevel).</li></ul> | ### Description <Warning> **Warning**: This config option is deprecated in Node.js package 2.2.6. Please use the [`logLevel`](#option-loglevel) option instead for Node.js package 2.2.6 and newer. </Warning> Enable debug logging, this is usually only needed on request from support. With this option enabled AppSignal will log a lot more information about decisions that are made during metrics collection and when data is sent to AppSignal.com servers. Enabling debug logging could have a slight impact on the disk usage and IO, especially on high-traffic sites. CPU overhead is minimal with the debug option enabled. <Note> This option sets the severity level of AppSignal's internal logger. This configuration option does not affect the [logging feature](/logging). </Note> ## disableDefaultInstrumentations <a /> | Field | Value | | ----------------------- | -------------------------------------------- | | Config file key | `disableDefaultInstrumentations` | | System environment key | `APPSIGNAL_DISABLE_DEFAULT_INSTRUMENTATIONS` | | Required | no | | Type | `list(String)` or Boolean (`true` / `false`) | | Default value | `false` | | Available since version | `3.0.0` | ### Description Allows you to disable the automatic instrumentation of default integrations: * @appsignal/opentelemetry-instrumentation-bullmq * @opentelemetry/instrumentation-amqplib * @opentelemetry/instrumentation-express * @opentelemetry/instrumentation-fastify * @opentelemetry/instrumentation-graphql * @opentelemetry/instrumentation-http * @opentelemetry/instrumentation-ioredis * @opentelemetry/instrumentation-knex * @opentelemetry/instrumentation-koa * @opentelemetry/instrumentation-mongodb * @opentelemetry/instrumentation-mongoose * @opentelemetry/instrumentation-mysql2 * @opentelemetry/instrumentation-mysql * @opentelemetry/instrumentation-nestjs-core * @opentelemetry/instrumentation-pg * @opentelemetry/instrumentation-redis * @opentelemetry/instrumentation-redis-4 * @opentelemetry/instrumentation-restify * @opentelemetry/instrumentation-undici * @prisma/instrumentation To disable all instrumentations, set the value to `true`. ## dnsServers <a /> | Field | Value | | ---------------------- | ----------------------- | | Config file key | `dnsServers` | | System environment key | `APPSIGNAL_DNS_SERVERS` | | Required | no | | Type | `list(String)` | | Default value | `[]` | ### Description Configure DNS servers for the AppSignal agent to use. ```sh Shell theme={null} # In the host environment export APPSIGNAL_DNS_SERVERS="8.8.8.8,8.8.4.4" ``` If you're affected by our [DNS timeouts](/support/known-issues#dns-timeouts), try setting a DNS server manually using this option that doesn't use more than **4** dots in the server name. * Acceptable values: `8.8.8.8`, `my.custom.local.server`. * Not acceptable values: `foo`, `my.awesome.custom.local.dns.server`. If the DNS server cannot be reached the agent will fall back on the host's DNS configuration and output a message in the `appsignal.log` file: `A problem occurred while setting DNS servers`. ## enableHostMetrics <a /> | Field | Value | | ---------------------- | ------------------------------- | | Config file key | `enableHostMetrics` | | System environment key | `APPSIGNAL_ENABLE_HOST_METRICS` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | \`\`true` / detected by system` | ### Description Set this option to `false` to disable [host metrics](/metrics/host-metrics) collection. On Heroku and Dokku host metrics are disabled by default. This is done because these systems will report inaccurate metrics from within the containers. Host metrics collection on these systems cannot be enabled. For Heroku, use the [Heroku log drain](/heroku/host-metrics) instead. ## enableMinutelyProbes <a /> | Field | Value | | ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Config file key | `enableMinutelyProbes` | | System environment key | `APPSIGNAL_ENABLE_MINUTELY_PROBES` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `true` | | Available since version | `0.4.0` | | | <ul><li>`2.3.0`: Support added for the environment variable option.</li><li>`2.3.0`: Disables the minutely probes system from reporting metrics. Before version `2.3.0` it only unregistered the default probes.</li></ul> | ### Description Enables the [minutely probes](/nodejs/3.x/instrumentation/minutely-probes) system. ## enableNginxMetrics <a /> | Field | Value | | ----------------------- | -------------------------------- | | Config file key | `enableNginxMetrics` | | System environment key | `APPSIGNAL_ENABLE_NGINX_METRICS` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `false` | | Available since version | `3.0.8` | ### Description Set to `true` to enable the NGINX metrics server. [See the NGINX metrics documentation for details.](/metrics/nginx) When enabled, the AppSignal agent will listen to a `localhost`-bound server on port 27649. If you're running several AppSignal-instrumented applications in the same server, this configuration option can only be enabled in one of them. ## enableOpentelemetryHttp <a /> | Field | Value | | ----------------------- | ------------------------------------- | | Config file key | `enableOpentelemetryHttp` | | System environment key | `APPSIGNAL_ENABLE_OPENTELEMETRY_HTTP` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `true` | | Available since version | `3.1.0` | ### Description Set this option to `true` to enable the [OpenTelemetry HTTP server](/standalone-agent/installation). When enabled, the AppSignal agent will listen to a `localhost`-bound server on port 8099. If you're running several AppSignal-instrumented applications in the same server, this configuration option can only be enabled in one of them. This is required for apps using the OpenTelemetry HTTP exporter to report data to AppSignal. ## enableStatsd <a /> | Field | Value | | ----------------------- | -------------------------- | | Config file key | `enableStatsd` | | System environment key | `APPSIGNAL_ENABLE_STATSD` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `false` | | Available since version | `2.2.2` | ### Description Enables the [StatsD server](/standalone-agent/statsd) in the AppSignal agent. When enabled, the AppSignal agent will listen to a `localhost`-bound server on port 8125. If you're running several AppSignal-instrumented applications in the same server, this configuration option can only be enabled in one of them. ## filesWorldAccessible <a /> | Field | Value | | ----------------------- | ---------------------------------- | | Config file key | `filesWorldAccessible` | | System environment key | `APPSIGNAL_FILES_WORLD_ACCESSIBLE` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `true` | | Available since version | `2.2.4` | ### Description If this is set to `true` the [AppSignal working directory](/appsignal/how-appsignal-operates#working-directory) that is created is accessible for all users (Unix permissions `0666`). This is often necessary because processes for the same app run under a different user. Set to `false` to disable this behaviour (Unix permissions `0644`). ## filterParameters <a /> | Field | Value | | ----------------------- | ----------------------------- | | Config file key | `filterParameters` | | System environment key | `APPSIGNAL_FILTER_PARAMETERS` | | Required | no | | Type | `list(String)` | | Default value | `[]` | | Available since version | `2.2.5` | ### Description List of parameter keys that should be ignored using AppSignal filtering. Their values will be replaced with `[FILTERED]` when transmitted to AppSignal. Read more about [parameter filtering](/application/parameter-filtering). ## filterSessionData <a /> | Field | Value | | ----------------------- | ------------------------------- | | Config file key | `filterSessionData` | | System environment key | `APPSIGNAL_FILTER_SESSION_DATA` | | Required | no | | Type | `list(String)` | | Default value | `[]` | | Available since version | `2.2.5` | ### Description List of session data keys that should be ignored using AppSignal filtering. Their values will be replaced with `[FILTERED]` when transmitted to AppSignal. Read more about [session data filtering](/application/session-data-filtering). ## hostname <a /> | Field | Value | | ---------------------- | -------------------- | | Config file key | `hostname` | | System environment key | `APPSIGNAL_HOSTNAME` | | Required | no | | Type | `String` | | Default value | detected from system | ### Description This overrides the server's hostname. Useful for when you're unable to set a custom hostname or when a nondescript id is generated for you on hosting services. ## hostRole <a /> | Field | Value | | ----------------------- | ------------------------- | | Config file key | `hostRole` | | System environment key | `APPSIGNAL_HOST_ROLE` | | Required | no | | Type | `String` | | Default value | `null` (unset by default) | | Available since version | `3.0.19` | ### Description Group hosts by role and generate metrics based on this role. One such metric is the `reporting_hosts` counter metric. A good role indicates what the main role of the server is, like "webserver", "processor", "api", "database", "loadbalancer", etc. ## httpProxy <a /> | Field | Value | | ---------------------- | ------------------------- | | Config file key | `httpProxy` | | System environment key | `APPSIGNAL_HTTP_PROXY` | | Required | no | | Type | `String` | | Default value | `null` (unset by default) | ### Description If you require the agent to connect to the Internet via a proxy set the complete proxy URL in this configuration key. ## ignoreActions <a /> | Field | Value | | ---------------------- | -------------------------- | | Config file key | `ignoreActions` | | System environment key | `APPSIGNAL_IGNORE_ACTIONS` | | Required | no | | Type | `list(String)` | | Default value | `[]` | ### Description With this config option you can specify a list of actions that will be ignored by AppSignal. Everything that happens including exceptions will not be transmitted to AppSignal. This can be useful to ignore health check endpoints or other actions that you don't want to monitor. Read more about [ignoring actions](/guides/filter-data/ignore-actions). ## ignoreErrors <a /> | Field | Value | | ---------------------- | ------------------------- | | Config file key | `ignoreErrors` | | System environment key | `APPSIGNAL_IGNORE_ERRORS` | | Required | no | | Type | `list(String)` | | Default value | `[]` | ### Description List of error classes that will be ignored. Any exception raised with this error class will not be transmitted to AppSignal. Read more about [ignoring errors](/guides/filter-data/ignore-errors). ## ignoreLogs <a /> | Field | Value | | ----------------------- | ----------------------- | | Config file key | `ignoreLogs` | | System environment key | `APPSIGNAL_IGNORE_LOGS` | | Required | no | | Type | `list(String)` | | Default value | `[]` | | Available since version | `3.4.0` | ### Description List of log messages that will be ignored. Any log message containing any of the elements of the list will not be transmitted to AppSignal. A small subset of regex syntax is supported, read more about it in our [Ignore Logs](/guides/filter-data/ignore-logs) guide. ## ignoreNamespaces <a /> | Field | Value | | ---------------------- | ----------------------------- | | Config file key | `ignoreNamespaces` | | System environment key | `APPSIGNAL_IGNORE_NAMESPACES` | | Required | no | | Type | `list(String)` | | Default value | `[]` | ### Description List of namespaces that will be ignored. Any error raised or slow request that occurs in this namespace will not be send to AppSignal. Read more about [namespaces](/application/namespaces). ## log <a /> | Field | Value | | ---------------------- | --------------- | | Config file key | `log` | | System environment key | `APPSIGNAL_LOG` | | Required | no | | Type | `String` | | Default value | `file` | ### Description <Note> This option configures what logger that AppSignal's internal logging functionality will use and does not affect the [logging feature](/logging). **Note**: The [AppSignal agent](/appsignal/how-appsignal-operates), which is used by the integration, will always write to the "appsignal.log" file. </Note> Select which logger the AppSignal integration will use. Accepted values are `file` and `stdout`. See also the `log_path` configuration. * `file` (default) * Write all AppSignal logs to the file system. * `stdout` (default on [Heroku](https://heroku.com)) * Print AppSignal logs in the parent process' STDOUT instead of to a file. Useful with hosting solutions such as container systems and Heroku. ## logLevel <a /> | Field | Value | | ----------------------- | --------------------- | | Config file key | `logLevel` | | System environment key | `APPSIGNAL_LOG_LEVEL` | | Required | no | | Type | `String` | | Default value | `info` | | Available since version | `2.2.6` | ### Description <Note> This option sets the severity level of AppSignal's internal logger and does not affect the [logging feature](/logging). </Note> Set the severity level of AppSignal's internal logger. If it is configured to "info" it will log all error, warning and info messages, but not log the debug messages. Setting it to the levels "debug" or "trace" is usually only needed on request from support. Setting the level to "debug"/"trace" could have a slight impact on the disk usage and IO, especially on high-traffic sites. CPU overhead is minimal with the debug option enabled. Accepted values: * error * warning * info * debug * trace ## logPath <a /> | Field | Value | | ---------------------- | -------------------- | | Config file key | `logPath` | | System environment key | `APPSIGNAL_LOG_PATH` | | Required | no | | Type | `String` | | Default value | `/tmp` | ### Description <Note> This option configures the location of AppSignal's internal logging file and does not affect the [logging feature](/logging). <br /> **Note**: The specified path cannot contain Operating Specific file system abstractions, such as the homedir symbol `~` for \*NIX systems. This will be seen as a malformed path. </Note> Override the location of the path (directory) where the `appsignal.log` file can be written to. ## nginxPort <a /> | Field | Value | | ----------------------- | ---------------------- | | Config file key | `nginxPort` | | System environment key | `APPSIGNAL_NGINX_PORT` | | Required | no | | Type | `Integer` | | Default value | `27649` | | Available since version | `3.6.7` | ### Description Configure the port on which the NGINX metrics server is exposed. When AppSignal receives NGINX metrics, it listens on a `localhost`-bound server, by default on port 27649. If you're running several AppSignal-instrumented applications in the same server with NGINX metrics enabled, use this option to configure each application to listen on a different port. ## opentelemetry\_port <a /> | Field | Value | | ----------------------- | ------------------------------ | | Config file key | `opentelemetry_port` | | System environment key | `APPSIGNAL_OPENTELEMETRY_PORT` | | Required | no | | Type | `String` | | Default value | `8099` | | Available since version | `3.1.0` | ### Description Set this option to configure the OpenTelemetry HTTP server port of the AppSignal agent process. Configure this port if another process is already running on the machine that is also using this port to avoid conflicts. ## requestHeaders <a /> | Field | Value | | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------ | | Config file key | `requestHeaders` | | System environment key | `APPSIGNAL_REQUEST_HEADERS` | | Required | no | | Type | `list(String)` | | Default value | `["accept", "accept-charset", "accept-encoding", "accept-language", "cache-control", "connection", "content-length", "range"]` | | Available since version | `2.2.5` | ### Description The `requestHeaders` config option contains a list of HTTP request headers which are read and stored by the AppSignal Node.js package. This `requestHeaders` config option is an *allowlist*, which means that it will only take headers as specified by this config option. If this config option is unset it will use the AppSignal default. Following list is the AppSignal package default. ```javascript Node.js theme={null} client = Appsignal.new( // ...Other config opts requestHeaders: [ "accept", "accept-charset", "accept-encoding", "accept-language", "cache-control", "connection", "content-length", "range" ] ) ``` To configure AppSignal to not store any HTTP request headers on AppSignal transactions, configure the option with an empty list. ```javascript Node.js theme={null} client = Appsignal.new( // ...Other config opts requestHeaders: [] ) ``` ## revision <a /> | Field | Value | | ----------------------- | ----------------------------------------------------------------------------------------------------------------- | | Config file key | `revision` | | System environment key | `APP_REVISION` | | Required | no | | Type | `String` | | Default value | `null` (unset by default) | | Available since version | `1.0.0` | | | <ul><li>`3.0.16`: Auto detection for Render deploys.</li><li>`3.4.4`: Auto detection for Kamal deploys.</li></ul> | ### Description Set the app revision to report the currently running version of your app. AppSignal will create a deploy marker when this value changes, and tag all incoming data with the current revision. When your application is deployed using Kamal, or when it is deployed to Render, or when it is deployed to Heroku and the [Heroku Labs: Dyno Metadata](https://devcenter.heroku.com/articles/dyno-metadata) feature is enabled, the AppSignal integration will automatically detect the Git commit of the current deployment and use it as the revision. You can overwrite the automatically detected revisions in Heroku, Render or Kamal by manually setting the `revision` config option to a custom value. Read more about deploy markers in the [deploy markers topic](/application/markers/deploy-markers). ## runningInContainer <a /> | Field | Value | | ---------------------- | -------------------------------- | | Config file key | `runningInContainer` | | System environment key | `APPSIGNAL_RUNNING_IN_CONTAINER` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | detected by agent | ### Description AppSignal expects to be running on the same machine between different deploys. Set this key to `true` if the application is running in a container, such as with Docker. Newer versions of the AppSignal integration automatically detect its container environment, so no manual configuration is necessary. If you're having trouble with the automatic detection, please [contact support](mailto:support@appsignal.com). This option is set to `true` automatically on [Heroku](http://heroku.com/). ## sendEnvironmentMetadata <a /> | Field | Value | | ----------------------- | ------------------------------------- | | Config file key | `sendEnvironmentMetadata` | | System environment key | `APPSIGNAL_SEND_ENVIRONMENT_METADATA` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `true` | | Available since version | `2.2.6` | ### Description Send environment metadata about the app. For more information please read about [environment metadata](/application/environment-metadata). ## sendParams <a /> | Field | Value | | ----------------------- | -------------------------- | | Config file key | `sendParams` | | System environment key | `APPSIGNAL_SEND_PARAMS` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `true` | | Available since version | `2.2.8` | ### Description Whether to skip sending request parameters to AppSignal. For more information please read about [send\_params](/application/parameter-filtering) in filtering request parameters. ## sendSessionData <a /> | Field | Value | | ----------------------- | ----------------------------- | | Config file key | `sendSessionData` | | System environment key | `APPSIGNAL_SEND_SESSION_DATA` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `true` | | Available since version | `2.2.9` | ### Description Set this option to `false` to not send any session data with exception traces and performance issue samples. For more information please read about [request session data filtering](/application/session-data-filtering). ## statsdPort <a /> | Field | Value | | ----------------------- | ----------------------- | | Config file key | `statsdPort` | | System environment key | `APPSIGNAL_STATSD_PORT` | | Required | no | | Type | `Integer` | | Default value | `8125` | | Available since version | `3.0.16` | ### Description Set this option to configure the StatsD HTTP server port of the AppSignal agent process. Configure this port if another process is already running on the machine that is also using this port to avoid conflicts. ## workingDirectoryPath <a /> | Field | Value | | ----------------------- | ---------------------------------- | | Config file key | `workingDirectoryPath` | | System environment key | `APPSIGNAL_WORKING_DIRECTORY_PATH` | | Required | no | | Type | `String` | | Default value | detected by agent | | Available since version | `1.0.0` | ### Description Override the location where AppSignal for Node.js can store temporary files. Use this option if the default location is not suitable. See our [how AppSignal operates](/appsignal/how-appsignal-operates) page for more information about the purpose of this working directory. If you are running multiple applications using AppSignal on the same server, use this configuration option to select different working directories for every AppSignal instance, otherwise the two instances could conflict with one another. For more information on this scenario see our [running multiple applications on one host](/guides/application/multiple-applications-on-one-host) documentation. ```javascript Node.js theme={null} // Example: appsignal.js const { Appsignal } = require("@appsignal/nodejs"); const appsignal = new Appsignal({ // Other config workingDirectoryPath: "/tmp/project_1" }); ``` <Note> **Note**: The specified path cannot contain Operating Specific file system abstractions, such as the homedir symbol `~` for \*NIX systems. This will be seen as a malformed path. </Note> # Installation Source: https://docs.appsignal.com/nodejs/3.x/installation Please follow the [installation guide](/guides/new-application) first, when adding a new application to AppSignal. ## Requirements Before you can compile the AppSignal package, make sure the build/compilation tools are installed for your system. Please check the [Supported Operating Systems](/support/operating-systems) page for any system dependencies that may be required. ## Installation First, [sign up](https://appsignal.com/users/sign_up) for an AppSignal account. Then, install AppSignal by following the instructions for your package manager. ### Using npm <CodeGroup> ```bash Bash theme={null} npm install @appsignal/nodejs ``` </CodeGroup> It's also possible to manually add the `@appsignal/nodejs` package to your `package.json`. Then, run `npm install`. <CodeGroup> ```json JSON theme={null} { "name": "my-app", "dependencies": { "@appsignal/nodejs": "^3.0.0" } } ``` </CodeGroup> Create an `appsignal.cjs` file to require and configure AppSignal. This file may also be placed in another location, like in the `src/` directory. For more information about the configuration, see our [configuration section](/nodejs/3.x/configuration). <CodeGroup> ```javascript Node.js theme={null} // appsignal.cjs const { Appsignal } = require("@appsignal/nodejs"); new Appsignal({ active: true, name: "<YOUR APPLICATION NAME>", pushApiKey: "<YOUR API KEY>", }); ``` </CodeGroup> ### Using pnpm pnpm suppresses lifecycle scripts for dependencies by default. The `@appsignal/nodejs` package relies on an `install` lifecycle script to download and compile its native extension. Without it, the extension won't load and AppSignal won't report any data. To install the package and allow its lifecycle script to run: <CodeGroup> ```bash Bash theme={null} pnpm --allow-build=@appsignal/nodejs add @appsignal/nodejs ``` </CodeGroup> ### Requiring the AppSignal client Now, you can run your application like you normally would, but use the `--require` flag to load AppSignal's instrumentation before any other library: <CodeGroup> ```shell Shell theme={null} node --require './appsignal.cjs' index.js ``` </CodeGroup> We recommend adding the `--require` flag to any script that starts your app: <CodeGroup> ```json JSON theme={null} { "scripts": { "server": "node --require ./appsignal.cjs index.js" } } ``` </CodeGroup> You can also use the `--require` flag with tools such as `ts-node` and `nodemon`. When using a wrapper CLI, such as `nest start` or `fastify start`, to start your application, use the `NODE_OPTIONS` environment variable to pass the flag to the Node.js runtime: <CodeGroup> ```sh Shell theme={null} NODE_OPTIONS='--require ./appsignal.cjs' nest start ``` </CodeGroup> <Warning> For the AppSignal integration to work correctly, the `appsignal.cjs` file **must** be required before any other dependencies. </Warning> ### TypeScript support AppSignal is fully compatible with TypeScript. When running a compiled TypeScript application with `node`, we recommend using [the `--enable-source-maps` Node.js flag](https://nodejs.org/api/cli.html#--enable-source-maps) so that error backtraces in AppSignal refer to locations in the original TypeScript code: <CodeGroup> ```sh Shell theme={null} node --enable-source-maps --require './appsignal.cjs' dist/src/main.js ``` </CodeGroup> When using a wrapper CLI, such as `nest start` or `fastify start`, to start your application, use the `NODE_OPTIONS` environment variable to pass the flag to the Node.js runtime: <CodeGroup> ```sh Shell theme={null} NODE_OPTIONS='--enable-source-maps --require ./appsignal.cjs' nest start ``` </CodeGroup> ### Import AppSignal Client The AppSignal client is accessed from the globally exported `Appsignal.client` object. To use features like [custom metrics](/metrics/custom), you must first import the AppSignal client: <CodeGroup> ```javascript Node.js theme={null} import { Appsignal } from "@appsignal/nodejs"; // or: const { Appsignal } = require("@appsignal/nodejs"); const client = Appsignal.client; ``` </CodeGroup> ### Adding integrations AppSignal supports several libraries and frameworks with additional packages, such as Express, Koa, Next.js and more. Additional installation instructions for these packages can be found in the [Node.js integrations section](/nodejs/3.x/integrations). *** <Note> πŸ“– Continue with our [installation guide](/guides/new-application). </Note> ## Uninstalling AppSignal for Node.js Uninstall AppSignal from your app by following the steps below. When these steps are completed your app will no longer send data to the AppSignal servers. 1. Run `npm uninstall @appsignal/nodejs` to uninstall the AppSignal for Node.js integration, or delete the line within the `dependencies` block of your application's `package.json` file referencing the `@appsignal/nodejs` package. 2. Run `npm install` to update your `package.lock` with the removed packages state. 3. Remove any AppSignal [configuration](/nodejs/3.x/configuration/) from your app. 4. Commit, deploy and restart your app. * This will make sure the AppSignal servers won't continue to receive data from your app. 5. Finally, [remove the app](/guides/application/deleting-applications) on AppSignal.com. <Note> πŸ“– Continue with our [uninstall guide](/guides/application/deleting-applications). </Note> ## Stopping The AppSignal Client AppSignal will stop automatically when your application or machine stops running. However, if you want to stop AppSignal manually you can run the following command: <CodeGroup> ```javascript Node.js theme={null} import { Appsignal } from "@appsignal/nodejs"; // or: const { Appsignal } = require("@appsignal/nodejs"); Appsignal.client.stop(); ``` </CodeGroup> # Instrumentation Source: https://docs.appsignal.com/nodejs/3.x/instrumentation AppSignal provides many ways to provide more insights into your application β€” by adding more instrumentation or tagging the data that appears in the UI at AppSignal.com. All of the information that we collect from your application forms part of a broader **trace**, a visual representation of the flow of data through your application. **Traces** are made of one or many spans. A Trace can be thought of as a *directed acyclic graph (DAG)* of spans: <img alt="Trace diagram" /> * [The Tracer object](/nodejs/3.x/instrumentation/instrumentation#the-tracer-object) * [Creating and using a span](/nodejs/3.x/instrumentation/instrumentation#creating-an-active-span) * [Exception handling](/nodejs/3.x/instrumentation/exception-handling) ## Contact us Don't hesitate to [contact us](mailto:support@appsignal.com) if you run into any issues while implementing tracing. We're here to help. # Additional OpenTelemetry instrumentations Source: https://docs.appsignal.com/nodejs/3.x/instrumentation/additional-instrumentations <Note> πŸ›Ÿ Don't hesitate to [contact us](mailto:support@appsignal.com) if you run into any issues while implementing custom instrumentations. We're here to help! </Note> In addition to the already included instrumentations, you can also add custom ones as long as they comply with the structure of an OpenTelemetry automatic instrumentation. ## Setup Using the [`additionalInstrumentations`](/nodejs/3.x/configuration/options#option-additionalinstrumentations) config option you can add additional instrumentations that will create spans and send them to AppSignal. Below is an example of how to use `additionalInstrumentations` in your application: <CodeGroup> ```javascript Node.js theme={null} const { CustomInstrumentation, } = require("opentelemetry-custom-instrumentation"); new Appsignal({ active: true, name: "<YOUR APPLICATION NAME>", pushApiKey: "<YOUR API KEY>", additionalInstrumentations: [ new CustomInstrumentation({ // instrumentation config here }), ], }); ``` </CodeGroup> # Exception handling Source: https://docs.appsignal.com/nodejs/3.x/instrumentation/exception-handling In most applications, some errors will get raised that aren't related to possible bugs in your code; they just happen when your app gets into contact with the real world, like when a bot tries to fill in a form. To avoid these errors from being raised as problems in AppSignal it's possible to add exception handling to your code or even let AppSignal completely ignore certain errors. ## Ignore errors The AppSignal configuration makes it possible to [ignore errors](/guides/filter-data/ignore-errors), by providing a list of specific error names in a denylist, AppSignal will not send alerts when these errors are raised. ## Record Exceptions To use the setError and sendError helpers you need to import them from `@appsignal/nodejs`: <CodeGroup> ```javascript Node.js theme={null} import { setError, sendError } from "@appsignal/nodejs"; ``` </CodeGroup> <Tip> The errors given as an argument to `sendError` and `setError` must be [`Error`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error)-like values. </Tip> ### Set Error If you want to catch exceptions in your application to prevent crashes, but still want to track the occurrence you can use `setError()` to add the error to your applications current active span. <CodeGroup> ```javascript Node.js theme={null} import { setError, sendError } from "@appsignal/nodejs" app.get("/kittens", (req, res) => { try { fetchAllKittens() } catch (err) { setError(err) } } ``` </CodeGroup> ### Send Error The `sendError()` function can be used to record an incident in a new root span. When using `sendError()`, the error is sent independently from the current context, so the sample for the request will not be marked as an error. Therefore it can be helpful to provide further context by using [non-child span helper functions](/nodejs/3.x/instrumentation/instrumentation#helpers). Unlike `setError()`, the `sendError()` function can be used in a context where there's no instrumentation such as a one-off script, or job queue. In the below example `setCustomData()` is used to add additional data to the error span. <CodeGroup> ```javascript Node.js theme={null} import { setError, sendError } from "@appsignal/nodejs" app.get("/kittens", (req, res) => { try { fetchAllKittens() } catch (err) { // oh no, we ran out of kittens! // let's keep a note that this happened... sendError(err, () => { setCustomData({ message: "We ran out of kittens!" }) }) // ...and go adopt some more! adoptMoreKittens() } } ``` </CodeGroup> The exception will be tracked by AppSignal like any other error, and it allows you to provide custom error handling and fallbacks. # Custom instrumentation for Node.js Source: https://docs.appsignal.com/nodejs/3.x/instrumentation/instrumentation <Note> πŸ›Ÿ Don't hesitate to [contact us](mailto:support@appsignal.com) if you run into any issues while implementing custom instrumentations. We're here to help! </Note> Including custom instrumentation in your application can be useful for identifying the specific lines of code causing performance problems. AppSignal provides [helpers](#helpers), which let you display relevant data about the state of your application alongside performance metrics to assist you in identifying the root causes of any performance problems your application may be experiencing. ## Setup To use AppSignal's helper functions in your instrumentation, you must first [import `opentelemetry` and define a tracer object](#import-opentelemetry-and-define-tracer). Depending on your instrumentation, you may also need to [create additional spans](#spans). Our [Example Use Cases](#example-use-cases) demonstrate how you can use tracers, spans, and helpers to create your custom instrumentation. ### Import OpenTelemetry and Define Tracer The AppSignal integration for Node.js uses OpenTelemetry tracer objects. These tracers contain various functions for creating custom instrumentations. The Tracer exposes functions for creating and creating new spans. This documentation will outline how you can use tracers and spans to implement your custom integration. You must first import the trace object from `@opentelemetry/api` before working with tracers and spans. By invoking the `getTracer` function on theΒ trace object a new tracer object can be created. You must give your tracer object a name in this function, as seen in the example below, where the `getTracer` function is used to define a tracer with the name `"my interesting app"`. <CodeGroup> ```javascript Node.js theme={null} import { trace } from "@opentelemetry/api"; const tracer = trace.getTracer("my-interesting-app"); ``` </CodeGroup> ### Spans A span is the name of the object that we use to capture data about the performance of your application, any errors and any surrounding context. A span forms part of a broader trace, a hierarchical representation of the flow of data through your application. Spans keep track of the start and end time of an event, along with other information, such as the name or other data related to it. You can read more about spans in the [OpenTelemetry Tracing Documentation](https://opentelemetry.io/docs/instrumentation/js/api/tracing/). ### Creating an Active Span New spans can be invoked via the [trace object](#import-opentelemetry-and-define-tracer). Code instrumented inside an Express of Koa handler will already be inside a span. You can create new spans by invoking the`startActiveSpan()` function on the tracer object. Newly created spans will be the child of the span they were created in, if one exists. You can use child spans to measure the performance of tasks executed from within a parent span. You should give your span a name that makes its purpose clear. Execute all of the tasks you wish to monitor within the `startActiveSpan()` function, like in the below example. <CodeGroup> ```javascript Node.js theme={null} tracer.startActiveSpan("printing coffee beans", async (span) => { const coffeeBeans = await fetchAllCoffeeBeans(); console.log(coffeeBeans); span.end(); }); ``` </CodeGroup> After the task is complete, you must close the span: `span.end()` ### Example Use Cases When implementing custom instrumentation, you may be curious to understand the behavior of particular functions, for example, how long it takes for them to execute. #### Using Helpers In the below example, we are curious about the performance of our "order-coffee" GET endpoint for different roasts of coffee. To investigate this, we use the `setAttribute` function to create a [tag](#tag) called flavor, the value we retrieve from request parameters. **Note:** Because this is inside an Express request handler, a root span has already been created. <CodeGroup> ```javascript Node.js theme={null} app.get('/order-coffee', (req, res) => { const roast = req.params.roast setTag("roast", roast) const coffeeBeans = pickCoffeeBeans(roast) prepareCoffeeBag(coffeeBeans) }) } ``` </CodeGroup> To get deeper insights into how our code is performing, we can use child spans to inspect functions called within our Express handler. The code below creates a child span of the `"picking coffee beans"` span defined in the `pickCoffeeBeans` function. Once the attribute has been assigned and all functions executed, we `.end()` the span to ensure AppSignal receives the start and finish time and attributes we've assigned: <CodeGroup> ```javascript Node.js theme={null} function pickCoffeeBeans(roast) { tracer.startActiveSpan("picking coffee beans", async (span) => { const roastBrands = { light: "Caffinated Cloud", medium: "Feeling The Buzz", dark: "The Jitters", }; const roastBrand = roastBrands[roast]; setTag("brand", roastBrand); await retrieveDrinkTypes(roastBrand); span.end(); }); } ``` </CodeGroup> In AppSignal, we can see performance data for this function. We can use the roast and batch tags to filter the data and gain greater insights into what parameters potentially influence how our application's code behaves. <img alt="Screen shot of tags" /> #### Active Spans While tags are helpful to analyse performance differences on the same function, it does not give us insight into the performance of any functions called from within our function. To give us greater insights into what's happening inside of the `pickCoffeeBeans()`, we create a new `activeSpan` and name it "picking coffee beans". All logic we wish to track is executed from within an async function. We `await` the promise returned by `retrieveDrinkTypes()`, so that we can track it's performance as a child span of the `"picking coffee beans"` span we created in `pickCoffeeBeans()`. <CodeGroup> ```javascript Node.js theme={null} function pickCoffeeBeans(roast) { tracer.startActiveSpan("picking coffee beans", async (span) => { const roastBrands = { light: "Caffinated Cloud", medium: "Feeling The Buzz", dark: "The Jitters", }; const roastBrand = roastBrands[roast]; await retrieveDrinkTypes(roastBrand); span.end(); }); } function retrieveDrinkTypes(roastBrand) { return new Promise((resolve) => { const span = tracer.startActiveSpan("Fetching coffee types"); const brandDrinks = { "Caffinated Cloud": ["americano", "capuccino"], "Feeling The Buzz": ["capuccino", "latte"], "The Jitters": ["espresso"], }; const drinkTypes = brandDrinks[roastBrand]; // we want to give our Barista's some time prepare the machine setTimeout(() => { resolve(drinkTypes); span.end(); }, 60000); }); } ``` </CodeGroup> With this instrumentation, AppSignal will provide insights into the performance of the `pickCoffeeBeans()`, which will include the performance data of the `retrieveDrinkTypes()` function, providing greater insight into what factors are impacting the overall performance of a function. ## Helpers <Warning> Data sent to AppSignal must not contain any personal data, such as names, email addresses, etc. It is your responsibility to ensure that your application's data is sanatized before being forwarded to AppSignal. When identifying a person is necessary your application must use alternative forms of identification such as a user ID, hash, or pseudonym. </Warning> To use helper functions, you must first import them from `@appsignal/nodejs`. In the example below the namespace the code is being executed in is being reported to AppSignal. All available helper functions are outlined in the [below documentation](/#helper-functions). <CodeGroup> ```javascript Node.js theme={null} import { setNamespace } from "@appsignal/nodejs"; setNamespace("web"); ``` </CodeGroup> All available helper functions for custom instrumentation attributes are outlined in the [list below](#helper-functions). ### Helper Functions <Tip> The code snippets for the helpers below assume your code is already being instrumented (for example, inside an Express or Koa request handler). If your code is not already instrumented, you must [create a span](#spans) and use the helpers inside of it. </Tip> * [Namespace](#namespace) * [Tag](#tag) * [Request Parameters](#request-parameters) * [Set Session Data](#set-session-data) * [Request Headers](#request-headers) * [Root Name](#root-name) * [Custom Data](#custom-data) * **[Child Span Helpers:](#child-span-helpers)** * [Category](#category) * [Name](#name) * [Body](#body) ### Namespace Sets the string value of the root span namespace. <CodeGroup> ```javascript JavaScript theme={null} import { setNamespace } from "@appsignal/nodejs"; setNamespace("app"); ``` </CodeGroup> ### Tag Sets a tag, for example from a request parameter, which can be used as a filter from within the AppSignal application. In the below example we create a tag called color with the value blue. You can configure tags with names relevant to the context of your application. <CodeGroup> ```javascript Node.js theme={null} import { setTag } from "@appsignal/nodejs"; setTag("color", "blue"); ``` </CodeGroup> ### Request Parameters An object that is serializable to JSON. Incoming request parameters request body and query parameters. <CodeGroup> ```javascript Node.js theme={null} import { setParams } from "@appsignal/nodejs"; const exampleParams = { action: "delete" }; setParams(exampleParams); ``` </CodeGroup> ### Set Session Data An object that is serializable to JSON. <CodeGroup> ```javascript Node.js theme={null} import { setSessionData } from "@appsignal/nodejs"; const exampleSessionData = { locale: "en-GB" }; setSessionData(exampleSessionData); ``` </CodeGroup> ### Request Headers A string containing the header value. <CodeGroup> ```javascript Node.js theme={null} import { setHeader } from "@appsignal/nodejs"; setHeader("Content-type", "application/json"); ``` </CodeGroup> ### Root Name Allows you to set the name of the trace. Samples are grouped into actions by their trace name. <CodeGroup> ```javascript Node.js theme={null} import { setRootName } from "@appsignal/nodejs"; // somewhere in your code where there's an active span... setRootName("The action name"); ``` </CodeGroup> #### Example Use Case Your application has an endpoint called `GET /coffee`. <CodeGroup> ```javascript Node.js theme={null} app.get("/coffee", (req, res) => { // ... }); ``` </CodeGroup> All requests to this endpoint will generate samples called `GET /coffee`, but your endpoint handles multiple actions: `coffee?action=buy`, and `coffee?action=sell`. <img alt="Span Without Root Name" /> While they all use the `GET /coffee` endpoint, they are conceptually very different and so it would make sense for them to be grouped separately in AppSignal rather than in the same `GET /coffee` sample. To do this, you can use the `setRootName()` helper: <CodeGroup> ```javascript Node.js theme={null} import { setRootName } from "@appsignal/nodejs"; app.get("/coffee", (req, res) => { if (req.query.action === "buy") { setRootName("Buy coffee"); // ... buy coffee } else if (req.query.action === "sell") { setRootName("Sell coffee"); // ... sell coffee } }); ``` </CodeGroup> Using `setRootName` will change the name of the root span, grouping the samples for the requests `coffee?action=buy` and `coffee?action=sell` into separate actions: <img alt="Root Name Span" /> ### Custom Data An object that is serializable to JSON. <CodeGroup> ```javascript Node.js theme={null} import { setCustomData } from "@appsignal/nodejs"; const exampleCustomData = { stroopwaffle: "true", coffee: "false" }; setCustomData(exampleCustomData); ``` </CodeGroup> ### Child Span Helpers The following helpers only apply to child spans. To create a child span, you must create a new [Active Span](#creating-an-active-span). New spans are automatically children of their parent span. #### Category A string containing the child span category. The name should use `.` to express the category's hierarchical inheritance. For example: `cafe.coffee.cupsize` <CodeGroup> ```javascript Node.js theme={null} import { setCategory } from "@appsignal/nodejs"; setCategory("category.name"); ``` </CodeGroup> #### Name A string containing the child span event timeline title. <CodeGroup> ```javascript Node.js theme={null} import { setName } from "@appsignal/nodejs"; setName("Users query"); ``` </CodeGroup> #### Body <Warning> πŸ” Do not send <strong>Personal Identifiable Information (PII)</strong> to AppSignal. Filter PII (e.g., names, emails) and use an ID, hash, or pseudonymized identifier instead. <br /> <br /> For <strong>HIPAA-covered entities</strong>, more info on signing a Business Associate Agreement (BAA) is available in our <a href="/support/business-add-ons">Business Add-Ons documentation</a>. </Warning> The span's body can include additional information about the event, like the HTTP request, the connected host, etc. Be sure to sanitize the information before adding it to the span so no Personal Identifiable Information is sent to AppSignal. This information will be visible for the span when hovering over the event timeline. To store SQL queries in the span's body, please use the [`setSqlBody` helper](#sql-body) instead. <CodeGroup> ```javascript Node.js theme={null} import { setBody } from "@appsignal/nodejs"; setBody("Span body"); ``` </CodeGroup> #### SQL body <Tip> Available since Node.js package 3.0.25. </Tip> Set a SQL query as the body of the span as it appears in the performance event timeline in the incident sample detail view. This is similar to the [`setBody` helper](#body), but is specialized for SQL queries. Any SQL query set as the body with this attribute will be sanitized to avoid sending PII (Personal Identifiable Information) data to our servers. See the [`setBody` helper](#body) for more details on how the body attribute works. When both the `setBody` and `setSqlBody` helpers are called on the same span, the `setSqlBody` helper's value is leading and the `setBody` helper's value will be ignored. <CodeGroup> ```javascript Node.js theme={null} import { setSqlBody } from "@appsignal/nodejs"; setSqlBody("SELECT * FROM users"); ``` </CodeGroup> # Minutely probes Source: https://docs.appsignal.com/nodejs/3.x/instrumentation/minutely-probes Minutely probes are a mechanism to periodically send custom metrics to AppSignal. In minutely intervals from when the probe was first created, a user-defined function can be called in which you can capture metrics to send them to AppSignal. Minutely probe functions are ran asynchronously. Starting with version `2.3.0`, you can enable or disable minutely probes entirely with the [`enableMinutelyProbes`](/nodejs/3.x/configuration/options#option-enableminutelyprobes) config option. ## Creating probes If you need to track custom metrics from your app, you can add your own probe(s). To register a probe, you must call the `probes.register()` method with two arguments: a probe name, and an anonymous function to be called once every minute. <CodeGroup> ```javascript Node.js theme={null} const meter = appsignal.metrics(); const probes = meter.probes(); // the callback is fired once every minute from when // `register` is called probes.register("database", () => { meter.setGauge("database_size", 10); }); ``` </CodeGroup> To ensure all minutely probes are ran in a timely manner, it is important to avoid blocking the event loop for long periods inside a minutely probe callback. ## Overriding default probes By default, `@appsignal/nodejs` configures a minutely probe which keeps track of Node.js V8 heap statistics. To disable this probe, use `probes.unregister()`: <CodeGroup> ```javascript Node.js theme={null} const probes = appsignal.metrics().probes(); probes.unregister("v8_stats"); ``` </CodeGroup> Before version `2.3.0`, `probes.unregister()` is not available. In versions before `2.3.0`, you can use the [`enableMinutelyProbes`](/nodejs/3.x/configuration/options#option-enableminutelyprobes) config option to disable the default probe. # Node.js Integrations Source: https://docs.appsignal.com/nodejs/3.x/integrations <Note> πŸ›Ÿ Don't hesitate to [contact us](mailto:support@appsignal.com) if you run into any issues with AppSignal's Node.js integrations. We're here to help! </Note> AppSignal works with many popular Node.js frameworks and libraries out-of-the-box, such as: * [Node.js Core](/nodejs/3.x/integrations/core) * [Apollo Gateway](/nodejs/3.x/integrations/apollo-gateway) * [BullMQ](/nodejs/3.x/integrations/bullmq) * [Elasticsearch](/nodejs/3.x/integrations/elasticsearch) * [Express](/nodejs/3.x/integrations/express) * [Fastify](/nodejs/3.x/integrations/fastify) * [GraphQL (such as Apollo Server or Yoga)](/nodejs/3.x/integrations/graphql) * [Knex.js](/nodejs/3.x/integrations/knexjs) * [Koa.js](/nodejs/3.x/integrations/koajs) * [MongoDB](/nodejs/3.x/integrations/mongo) * [Mongoose](/nodejs/3.x/integrations/mongoose) * [MySQL (mysql and mysql2 packages)](/nodejs/3.x/integrations/mysql) * [NestJS](/nodejs/3.x/integrations/nestjs) * [Next.js](/nodejs/3.x/integrations/nextjs) * [PostgreSQL](/nodejs/3.x/integrations/pg) * [Prisma](/nodejs/3.x/integrations/prisma) * [Redis (redis and ioredis packages)](/nodejs/3.x/integrations/redis) * [Remix](/nodejs/3.x/integrations/remix) * [Restify](/nodejs/3.x/integrations/restify) More integrations and plugins are being added all the time! Check our [issues page on GitHub](https://github.com/appsignal/appsignal-nodejs/issues) to see if we're working on something for your chosen framework or library. <Note> Default instrumentations can be disabled via the `disableDefaultInstrumentations` config option. You can read more about how to configure this in our [Configuration Options documentation](/nodejs/3.x/configuration/options#option-disabledefaultinstrumentations). </Note> # amqplib Source: https://docs.appsignal.com/nodejs/3.x/integrations/amqplib <VersionRequirements /> Advanced Message Queuing Protocol (AMQP) is an open standard protocol that facilitates messaging interoperability across systems, regardless of the message broker vendor or platform they utilize, for example between STOMP and MQTT brokers. The AppSignal for Node.js integration for [amqplib](https://www.npmjs.com/package/amqplib) and compatible packages such as [Rascal](https://www.npmjs.com/package/rascal) allows you to instrument the sending and receiving of messages in your application. ## Installation The amqplib package is instrumented automatically by the AppSignal for Node.js package. ## Features When using the amqplib integration, AppSignal will create a child span for each message that is sent or received. Note that if the messages are received/sent outside of an instrumented context, such as a web request or background job, it's required to manually create a span to wrap the message processing. Below is an example for Rascal using the simplest example found on their repository, with manual instrumentation added to wrap the message processing in a span. <CodeGroup> ```javascript Node.js theme={null} let Rascal = require("../.."); let config = require("./config"); const trace = require("@opentelemetry/api"); const tracer = trace.getTracer("example-tracer"); Rascal.Broker.create(Rascal.withDefaultConfig(config), function (err, broker) { if (err) throw err; broker.subscribe("demo_sub", function (err, subscription) { if (err) throw err; subscription.on("message", function (message, content, ackOrNack) { tracer.startActiveSpan("received message demo_sub", (span) => { // Process the message ackOrNack(); span.end(); }); }); }); broker.on("error", console.error); setInterval(function () { broker.publish( "demo_pub", new Date().toISOString() + ": hello world", function (err, publication) { tracer.startActiveSpan("sent message demo_pub", (span) => { if (err) throw err; span.end(); }); } ); }, 1000); }); ``` </CodeGroup> For more information about manual instrumentation, see the [custom instrumentation guide](/nodejs/3.x/instrumentation/instrumentation). # Apollo Gateway Source: https://docs.appsignal.com/nodejs/3.x/integrations/apollo-gateway <VersionRequirements /> ## Installation and usage To use the Apollo Gateway instrumentation, you need to disable the GraphQL instrumentation in the service that acts as the gateway. This is because the gateway will send its own spans using the `@apollo/gateway` OpenTelemetry instrumentation for the queries it proxies to the services that implements in the supergraph. To do so, you can use the `disableInstrumentations` option in the `appsignal` configuration. <CodeGroup> ```javascript Node.js theme={null} const { Appsignal } = require("@appsignal/nodejs"); new Appsignal({ active: true, name: "your-app-name", pushApiKey: "your-push-api-key", disableDefaultInstrumentations: ["@opentelemetry/instrumentation-graphql"], }); ``` </CodeGroup> You also need to enable the OpenTelemetry instrumentation in your Apollo Gateway config: <CodeGroup> ```javascript Node.js theme={null} const config = { telemetry: { includeDocument: true, reportExceptions: 1, }, }; ``` </CodeGroup> ## Features The Apollo Gateway instrumentation will send root spans to AppSignal based on the queries it receives and routes to the subgraphs. You will be able to inspect this data in the Event timeline of performance issues: <img alt="Screenshot of Event timeline showing gateway.request events" /> If your federated services are also instrumented with AppSignal, you'll get the usual GraphQL spans for them as well. # BullMQ Source: https://docs.appsignal.com/nodejs/3.x/integrations/bullmq <VersionRequirements /> BullMQ is a Node.js job queue library backed by Redis. The AppSignal for Node.js integration for [BullMQ](https://bullmq.io/) instruments the enqueueing and processing in your application. ## Installation The BullMQ package is instrumented automatically by the AppSignal for Node.js package. If you run your workers as separate processes, make sure to also use `node --require appsignal.cjs ...` when starting the worker processes, so that AppSignal can instrument the workers' job processing. ## Features When using the BullMQ integration, AppSignal will create a performance sample for each job that is processed by a worker. When a job is enqueued in an instrumented context, such as a web request or background job, AppSignal will display an event in the performance sample's event timeline representing the job enqueueing. # Node.js Core Source: https://docs.appsignal.com/nodejs/3.x/integrations/core <Note> Default instrumentations can be disabled via the `disableDefaultInstrumentations` config option. You can read more about how to configure this in our [Configuration Options documentation](/nodejs/3.x/configuration/options#option-disabledefaultinstrumentations). </Note> Node.js contains several internal modules designed to enable asynchronous I/O capable APIs for your application. AppSignal provides automatic instrumentation for many of these modules. ## `http` and `https` instrumentation AppSignal for Node.js will auto-instrument any incoming and outgoing HTTP(S) requests. Incoming requests will appear as the root span of a trace, while outgoing requests will appear as child spans of an incoming request root span. For incoming requests to be instrumented in detail, you must use a supported web framework such as [Express](/nodejs/3.x/integrations/express), [Koa.js](/nodejs/3.x/integrations/koajs) or [NestJS](/nodejs/3.x/integrations/nestjs). ## Heap statistics minutely probe By default, Appsignal for Node.js will register a minutely probe that keeps track of the V8 engine's heap statistics. Once we detect these metrics we'll add a [magic dashboard](https://blog.appsignal.com/2019/03/27/magic-dashboards.html) to your app. The metrics reported by this method correspond to those reported by the `v8.getHeapStatistics` method in the Node.js standard library. For more details on how to interpret these metrics, [see the official Node.js documentation on the `v8` module](https://nodejs.org/api/v8.html#v8getheapstatistics). The probe will report the following metrics grouped by `hostname` tag: * `nodejs_total_heap_size` - gauge * `nodejs_total_heap_size_executable` - gauge * `nodejs_total_physical_size` - gauge * `nodejs_used_heap_size` - gauge * `nodejs_malloced_memory` - gauge * `nodejs_number_of_native_contexts` - gauge * `nodejs_number_of_detached_contexts` - gauge # Elasticsearch Source: https://docs.appsignal.com/nodejs/3.x/integrations/elasticsearch <VersionRequirements /> [Elasticsearch](https://www.elastic.co/elasticsearch) is a popular search and analytics engine. The AppSignal for Node.js integration for Elasticsearch provides automatic instrumentation for the [Elasticsearch Node.js client](https://github.com/elastic/elasticsearch-js). ## Installation The Elasticsearch Node.js client includes instrumentation via OpenTelemetry. It will automatically report data to the AppSignal for Node.js package. No additional setup is required to instrument Elasticsearch in your application. ## Features The built-in instrumentation captures spans for search queries, index operations, and other interactions with your Elasticsearch cluster. The integration will send AppSignal spans representing the execution time of each Elasticsearch API call with information about the operation. ## Configuration <Warning> The automatic instrumentation can be disabled starting from version `9.x` of `@elastic/elasticsearch`. If you are using version `8.x` of `@elastic/elasticsearch` make sure you are using `@elastic/transport` version `8.10.0` or higher. </Warning> You can disable the instrumentation of Elasticsearch by: * setting an environment variable; <CodeGroup> ```bash Shell theme={null} OTEL_ELASTICSEARCH_ENABLED=false ``` </CodeGroup> * using a custom `Transport`. <CodeGroup> ```typescript title="app.ts" theme={null} import { Transport, TransportRequestOptions, TransportRequestParams, } from "@elastic/transport"; class CustomTransport extends Transport { async request( params: TransportRequestParams, options: TransportRequestOptions = {}, ): Promise<any> { options.openTelemetry = { enabled: false }; return super.request(params, options); } } const client = new Client({ /* your client config... */ Transport: CustomTransport, }); ``` </CodeGroup> You can also leave the instrumentation enabled and **disable it for a single API call** by passing a custom `TransportRequestOptions` object as the second argument to any API call: <CodeGroup> ```typescript TypeScript theme={null} const response = await client.search({ ... }, { openTelemetry: { enabled: false }, }); ``` </CodeGroup> # Express Source: https://docs.appsignal.com/nodejs/3.x/integrations/express <VersionRequirements /> <Note> Default instrumentations can be disabled via the `disableDefaultInstrumentations` config option. You can read more about how to configure this in our [Configuration Options documentation](/nodejs/3.x/configuration/options#option-disabledefaultinstrumentations). </Note> The AppSignal for Node.js integration for [Express](https://expressjs.com/). ## Installation Express is instrumented automatically by the AppSignal for Node.js package. In order for errors occurring in your Express application to be forwarded to AppSignal, follow the instructions below to setup the error handler middleware. ## Error Handler The module contains middleware to send any errors that take place in your Express application to AppSignal. <CodeGroup> ```javascript Node.js theme={null} import { expressErrorHandler } from "@appsignal/nodejs"; // or: const { expressErrorHandler } = require("@appsignal/nodejs"); const app = express(); // add this after all routes, but before any other error handlers app.use(expressErrorHandler()); ``` </CodeGroup> <Tip> Only exceptions with status code 500 and above will be reported to AppSignal automatically. To send exceptions to AppSignal with other status codes, you can use [custom exception handling](/nodejs/3.x/instrumentation/exception-handling). </Tip> ## Features The Express integration will send AppSignal a child span representing the execution time of each middleware, as well as a child span for the request handler. The integration will use the request route as the name of the action. Request query parameters will be sent. The request body will be sent if `req.body` is present (for example, when using a body parsing middleware such as `body-parser`) The request cookies will be sent if `req.cookies` is present (for example, when using a cookie parsing middleware such as `cookie-parser`) When using the error handler middleware, any errors raised by the request handler or any of the middlewares will be reported to AppSignal. # Fastify Source: https://docs.appsignal.com/nodejs/3.x/integrations/fastify <VersionRequirements /> <Note> Default instrumentations can be disabled via the `disableDefaultInstrumentations` config option. You can read more about how to configure this in our [Configuration Options documentation](/nodejs/3.x/configuration/options#option-disabledefaultinstrumentations). </Note> The AppSignal for Node.js integration for Fastify. ## Installation Fastify is automatically instrumented by the AppSignal for Node.js package. To initialize the AppSignal client, you should require the `appsignal.cjs` file before your application starts loading. When calling `fastify start` directly, you can use the `NODE_OPTIONS` environment variable to require it: <CodeGroup> ```bash Bash theme={null} NODE_OPTIONS='--require ./appsignal.cjs' fastify start [...] ``` </CodeGroup> The start script references the `appsignal.cjs` file that was created [when configuring AppSignal](/nodejs/3.x/configuration#minimal-required-configuration). ## Features The Fastify integration will send AppSignal a child span representing the execution time of each component used during a web request. The integration will use the request route as the name of the action. Query params and request body are set as span attributes. Errors are automatically tracked. # GraphQL Source: https://docs.appsignal.com/nodejs/3.x/integrations/graphql <VersionRequirements /> <Note> Default instrumentations can be disabled via the `disableDefaultInstrumentations` config option. You can read more about how to configure this in our [Configuration Options documentation](/nodejs/3.x/configuration/options#option-disabledefaultinstrumentations). </Note> The AppSignal for Node.js integration for GraphQL, using the [`graphql`](https://www.npmjs.com/package/graphql) package. This instrumentation will also work with any library that depends on the `graphql` package, such as [Apollo Server](https://www.apollographql.com/) or [Yoga](https://www.the-guild.dev/graphql/yoga-server). ## Installation and usage GraphQL is instrumented automatically by the AppSignal for Node.js package. No additional setup is required to instrument GraphQL in your application. ## Features The GraphQL integration will send AppSignal child spans representing the parsing, validation, execution and resolution of the query. The span for the execution step will contain the GraphQL query. Any errors that occur when validating the query will be reported to AppSignal. # Knex.js Source: https://docs.appsignal.com/nodejs/3.x/integrations/knexjs <VersionRequirements /> <Note> Default instrumentations can be disabled via the `disableDefaultInstrumentations` config option. You can read more about how to configure this in our [Configuration Options documentation](/nodejs/3.x/configuration/options#option-disabledefaultinstrumentations). </Note> The AppSignal for Node.js integration for [Knex.js](https://knexjs.org/). This instrumentation will also work with any library that depends on the `knex` package, such as [Bookshelf.js](https://bookshelfjs.org/). ## Installation Knex.js is instrumented automatically by the AppSignal for Node.js package. No additional setup is required to instrument your Knex.js application. ## Features The Knex.js integration will record a child span representing the execution time of each query and containing the SQL query sanitized. # Koa.js Source: https://docs.appsignal.com/nodejs/3.x/integrations/koajs <VersionRequirements /> <Note> Default instrumentations can be disabled via the `disableDefaultInstrumentations` config option. You can read more about how to configure this in our [Configuration Options documentation](/nodejs/3.x/configuration/options#option-disabledefaultinstrumentations). </Note> The AppSignal for Node.js integration for [Koa.js](https://koajs.com/) (`koa`) v2.0.0+. ## Installation Koa.js is instrumented automatically by the AppSignal for Node.js package. No additional setup is required to instrument your Koa.js application. ## Features The Koa.js integration will send AppSignal a child span representing the execution time of each middleware, as well as a child span for the request handler. If using [`@koa/router`](https://www.npmjs.com/package/@koa/router), the integration will use the request route as the name of the action. Request query parameters will be sent. Any errors raised by the request handler or any of the middlewares will be reported to AppSignal. # MongoDB Source: https://docs.appsignal.com/nodejs/3.x/integrations/mongo <VersionRequirements /> <Note> Default instrumentations can be disabled via the `disableDefaultInstrumentations` config option. You can read more about how to configure this in our [Configuration Options documentation](/nodejs/3.x/configuration/options#option-disabledefaultinstrumentations). </Note> The AppSignal for Node.js integration for MongoDB v3.3+. ## Installation The MongoDB client library is instrumented automatically by the AppSignal for Node.js package. No additional setup is required to instrument MongoDB in your application. ## Features The MongoDB integration will send AppSignal a child span for each operation performed. The child span represents the duration of the query, and the name of the span contains the name of the collection queried and the operation that was performed. The body of the span contains a sanitised representation of the MongoDB query. # Mongoose Source: https://docs.appsignal.com/nodejs/3.x/integrations/mongoose <VersionRequirements /> <Note> Default instrumentations can be disabled via the `disableDefaultInstrumentations` config option. You can read more about how to configure this in our [Configuration Options documentation](/nodejs/3.x/configuration/options#option-disabledefaultinstrumentations). </Note> The AppSignal for Node.js integration for Mongoose. ## Installation The Mongoose client library is instrumented automatically by the AppSignal for Node.js package. You do not need to perform any additional setup to instrument Mongoose in your application. ## Features The Mongoose integration will send AppSignal a child span for each operation performed against a model. The child span represents the duration of the query, and the name of the span contains the name of the model used and the operation that was performed on that model. # MySQL Source: https://docs.appsignal.com/nodejs/3.x/integrations/mysql <VersionRequirements /> <Note> Default instrumentations can be disabled via the `disableDefaultInstrumentations` config option. You can read more about how to configure this in our [Configuration Options documentation](/nodejs/3.x/configuration/options#option-disabledefaultinstrumentations). </Note> The AppSignal for Node.js integration for MySQL, using the [`mysql`](https://www.npmjs.com/package/mysql) and [`mysql2`](https://www.npmjs.com/package/mysql2) packages. ## Installation The MySQL client library is instrumented automatically by the AppSignal for Node.js package. No additional setup is required to instrument MySQL in your application. ## Features The MySQL integration will send AppSignal a child span for each query. The child span represents the duration of the query and contains the SQL query sanitized. This instrumentation will also work with any library that depends on the `mysql` or `mysql2` packages as its database adapter, such as [Knex](https://github.com/knex/knex) or [TypeORM](https://github.com/typeorm/typeorm). # NestJS Source: https://docs.appsignal.com/nodejs/3.x/integrations/nestjs <VersionRequirements /> <Note> Default instrumentations can be disabled via the `disableDefaultInstrumentations` config option. You can read more about how to configure this in our [Configuration Options documentation](/nodejs/3.x/configuration/options#option-disabledefaultinstrumentations). </Note> The AppSignal for Node.js integration for [NestJS](https://nestjs.com/). ## Installation NestJS is instrumented automatically by the AppSignal for Node.js package. When calling `nest start` directly, you can use the `NODE_OPTIONS` environment variable to require it: <CodeGroup> ```bash Bash theme={null} NODE_OPTIONS='--require ./appsignal.cjs' nest start ``` </CodeGroup> The start script references the `appsignal.cjs` file that was created [when configuring AppSignal](/nodejs/3.x/configuration#minimal-required-configuration). To use AppSignal from the `npm` commands generated when creating an application with the `nest new` command, modify the following scripts from the `scripts` section of your `package.json` file as follows: <CodeGroup> ```json JSON theme={null} { "scripts": { "start": "NODE_OPTIONS='--require ./appsignal.cjs' nest start", "start:dev": "NODE_OPTIONS='--require ./appsignal.cjs' nest start --watch", "start:debug": "NODE_OPTIONS='--require ./appsignal.cjs' nest start --debug --watch", "start:prod": "node --require ./appsignal.cjs dist/main" } } ``` </CodeGroup> ## Features The NestJS integration will send AppSignal a child span representing the execution time of each middleware, as well as a child span for the request handler. The name of the controller class and method that handled the request will be used as the name of the action. Any errors raised by your NestJS application will be reported to AppSignal. # Next.js Source: https://docs.appsignal.com/nodejs/3.x/integrations/nextjs <VersionRequirements /> The AppSignal integration for [Next.js](https://nextjs.org/). To report both back-end traces and front-end errors, it is recommended to use `@appsignal/nodejs` in combination with [`@appsignal/javascript`](/front-end) and [`@appsignal/react`](/front-end/integrations/react) on the client-side for full-stack performance monitoring and error tracking. <Tip> Due to technical limitations of the AppSignal agent, it is not possible to use `@appsignal/nodejs` on Vercel's serverless environment. We recommend using our [Vercel log drain](/vercel/logs) and our [front-end JavaScript](/front-end) and [React](/front-end/integrations/react) packages instead. </Tip> ## Installation First, follow the [`@appsignal/nodejs` installation instructions](/nodejs/3.x/installation). Then, modify your Next project's `next.config.js` configuration file in order to enable instrumentation hooks: If you are using Next 15: <CodeGroup> ```javascript JavaScript theme={null} const nextConfig = { serverExternalPackages: ["@appsignal/nodejs"], }; ``` </CodeGroup> If you are using Next 13 or 14: <CodeGroup> ```javascript JavaScript theme={null} const nextConfig = { // Add the `experimental` object if not present experimental: { // Add the following lines inside the object instrumentationHook: true, serverComponentsExternalPackages: ["@appsignal/nodejs"], }, }; ``` </CodeGroup> Then, add the following file to the root of your Next.js project as `instrumentation.js`: <Tip> If your project has an `src` directory, then the `instrumentation.js` file should be placed in that directory. If your project is using the [Next.js App Router](https://nextjs.org/docs/app/building-your-application/routing/defining-routes), the file should not be placed inside the `app` folder, but in the folder that contains the `app` folder. </Tip> <CodeGroup> ```javascript JavaScript theme={null} export function register() { if (process.env.NEXT_RUNTIME === "nodejs") { require("./appsignal.cjs"); } } ``` </CodeGroup> The instrumentation hook file references the `appsignal.cjs` file that was created [when configuring AppSignal](/nodejs/3.x/configuration#minimal-required-configuration). Make sure that the `appsignal.cjs` file is in the same folder as the `instrumentation.js` file, or adjust the path of the `require` in the `instrumentation.js` file accordingly. Finally, modify your `appsignal.cjs` configuration file in order to disable the HTTP instrumentation, which would otherwise generate redundant traces: <CodeGroup> ```javascript JavaScript theme={null} const { Appsignal } = require("@appsignal/nodejs"); new Appsignal({ // Add the `disableDefaultInstrumentations` list if not present disableDefaultInstrumentations: [ // Add the following line inside the list "@opentelemetry/instrumentation-http", ], }); ``` </CodeGroup> ### TypeScript support When using TypeScript, the backtraces emitted by server-side Next.js errors will refer to the compiled JavaScript files. Follow these steps to configure Next.js so that the backtraces refer to the original TypeScript code. First, configure Next.js to emit source maps by adding the following lines to your application's `next.config.js` file: <CodeGroup> ```javascript JavaScript theme={null} const nextConfig = { // Add the `webpack` function if not present webpack: (config, { isServer }) => { // Add the following lines inside the function if (isServer) { config.devtool = "eval-source-map"; } return config; }, }; ``` </CodeGroup> Then, in your `package.json`, modify how your Next.js application is started when running `npm run start`, using the `NODE_OPTIONS` environment variable to pass the `--enable-source-maps` flag to the Node.js runtime: <CodeGroup> ```json JSON theme={null} { "scripts": { // Modify the `start` script as follows "start": "NODE_OPTIONS=--enable-source-maps next start" } } ``` </CodeGroup> Finally, if using the `@appsignal/javascript` front-end integration package to track client-side errors, add the `productionBrowserSourceMaps` option to the `next.config.js` file for Next.js to emit public source maps: <CodeGroup> ```javascript JavaScript theme={null} const nextConfig = { // Add the `productionBrowserSourceMaps` flag productionBrowserSourceMaps: true, }; ``` </CodeGroup> ## Features The Next.js integration will send AppSignal a performance sample for each request. Within each sample, the event timeline will show events, along with their duration, corresponding to: * Rendering the document * Running the `getServerSideProps` function *(pages router only)* * Running the route handler * Performing HTTP requests using Next.js' server-side `fetch` *(app router only)* ## Standalone output No data may be reported when Next.js is configured with `output: "standalone"` in `next.config.js`. When Next.js optimizes its app size to only include what is used by the app, it omits the AppSignal extension and agent, which report the data to our servers. When using the [Next.js "with-docker" starter](https://github.com/vercel/next.js/tree/canary/examples/with-docker), specifically the [Dockerfile](https://github.com/vercel/next.js/blob/canary/examples/with-docker/Dockerfile), a modification is required to make sure the AppSignal extension and agent are included in the production Docker image. Add the following line to your `Dockerfile`, after similar `COPY` lines near the end of the file: <CodeGroup> ```docker Dockerfile theme={null} # Dockerfile COPY --from=builder --chown=nextjs:nodejs /app/node_modules/@appsignal/nodejs ./node_modules/@appsignal/nodejs ``` </CodeGroup> The change in Git will look something like this, but your Dockerfile may be slightly different: <CodeGroup> ```diff Diff theme={null} --- Dockerfile +++ Dockerfile @@ -48,6 +48,7 @@ COPY --from=builder /app/public ./public # https://nextjs.org/docs/advanced-features/output-file-tracing COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./ COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static +COPY --from=builder --chown=nextjs:nodejs /app/node_modules/@appsignal/nodejs ./node_modules/@appsignal/nodejs USER nextjs ``` </CodeGroup> # PostgreSQL client Source: https://docs.appsignal.com/nodejs/3.x/integrations/pg <VersionRequirements /> <Note> Default instrumentations can be disabled via the `disableDefaultInstrumentations` config option. You can read more about how to configure this in our [Configuration Options documentation](/nodejs/3.x/configuration/options#option-disabledefaultinstrumentations). </Note> The AppSignal for Node.js integration for PostgreSQL, using the [`pg` package](https://www.npmjs.com/package/pg). ## Installation The PostgreSQL client is instrumented automatically by the AppSignal for Node.js package. No additional setup is required to instrument PostgreSQL in your application. ## Features The PostgreSQL integration will send AppSignal a child span for each query. The child span represents the duration of the query and contains the SQL query sanitized. This instrumentation will also work with any library that depends on the `pg` package as its database adapter, such as [Knex](https://github.com/knex/knex) or [TypeORM](https://github.com/typeorm/typeorm). # Prisma Source: https://docs.appsignal.com/nodejs/3.x/integrations/prisma <VersionRequirements /> <Note> Default instrumentations can be disabled via the `disableDefaultInstrumentations` config option. You can read more about how to configure this in our [Configuration Options documentation](/nodejs/3.x/configuration/options#option-disabledefaultinstrumentations). </Note> The AppSignal for Node.js integration for Prisma. Prisma is an ORM (Object Relation Mapping) tool for Node.js that allows you to manage and interact with your application's database. You can learn more about Prisma on their [official website](https://www.prisma.io/). ## Installation Starting from Prisma version `v6.1.0`, Prisma is automatically instrumented by the AppSignal for Node.js package. No additional installation or configuration steps are required. ## Features The Prisma integration will send AppSignal a child span for each query, along with other child spans representing the connection to the database and the serialisation process. The child span for the query represents the duration of the query and contains the sanitized SQL query. If using Mongo, it contains the model and method name that was queried. # Redis Source: https://docs.appsignal.com/nodejs/3.x/integrations/redis <VersionRequirements /> <Note> Default instrumentations can be disabled via the `disableDefaultInstrumentations` config option. You can read more about how to configure this in our [Configuration Options documentation](/nodejs/3.x/configuration/options#option-disabledefaultinstrumentations). </Note> The AppSignal for Node.js integration for Redis, using the [`redis`](https://www.npmjs.com/package/redis) and [`ioredis`](https://www.npmjs.com/package/ioredis) packages. ## Installation The Redis client is instrumented automatically by the AppSignal for Node.js package. No additional setup is required to instrument Redis in your application. ## Features The Redis integration will send AppSignal a child span for each query. The child span represents the duration of the query and contains the query type. This instrumentation will also work with any library that depends on the `redis` or `ioredis` packages as its database adapter. # Remix Source: https://docs.appsignal.com/nodejs/3.x/integrations/remix <VersionRequirements /> The AppSignal for Node.js integration for [Remix](https://remix.run/) ## Installation To enable the instrumentation support for Remix, you first need to install the [OpenTelemetry Remix Instrumentation](https://www.npmjs.com/package/opentelemetry-instrumentation-remix) `^0.5.0` package. After installing the OpenTelemetry Remix Instrumentation package, you must enable the instrumentation in the AppSignal client initialization using the [`additionalInstrumentations`](/nodejs/3.x/configuration/options#option-additionalinstrumentations) config option as shown in the code below. <CodeGroup> ```javascript Node.js theme={null} // appsignal.cjs const { Appsignal } = require("@appsignal/nodejs"); const { RemixInstrumentation } = require("opentelemetry-instrumentation-remix"); new Appsignal({ active: true, name: "<YOUR APPLICATION NAME>", pushApiKey: "<YOUR API KEY>", additionalInstrumentations: [new RemixInstrumentation()], }); ``` </CodeGroup> This snippet references the `appsignal.cjs` file that was created [when configuring AppSignal](/nodejs/3.x/configuration#minimal-required-configuration). You must set the `NODE_OPTIONS` environment variable to load the `appsignal.cjs` file when starting your Remix app. <CodeGroup> ```bash Bash theme={null} NODE_OPTIONS='--require ./appsignal.cjs' remix dev ``` </CodeGroup> <Tip> Remix is built on top of Express for web requests handling, and that could make your actions in AppSignal harder to read. If that's your case, you can disable the Express instrumentation by passing the `disableInstrumentations` option to the AppSignal client initialization with the value: `["@opentelemetry/instrumentation-express"]`. </Tip> ## Features The Remix instrumentation will create performance actions in AppSignal from the Remix request handlers. The action name will be the route of the request handler. Remix loaders are instrumented as child spans of the request handler span. Once configured, errors raised by your Remix application will be reported to AppSignal. # Restify Source: https://docs.appsignal.com/nodejs/3.x/integrations/restify <VersionRequirements /> <Note> Default instrumentations can be disabled via the `disableDefaultInstrumentations` config option. You can read more about how to configure this in our [Configuration Options documentation](/nodejs/3.x/configuration/options#option-disabledefaultinstrumentations). </Note> The AppSignal for Node.js integration for [restify](http://restify.com/). ## Installation Applications using restify are instrumented automatically by the AppSignal for Node.js package. No additional setup is required to instrument your restify application. ## Features The restify integration will send AppSignal a child span representing the execution time of each middleware, as well as a child span for the request handler. Any errors raised by your restify application will be reported to AppSignal. # Migration Guide Source: https://docs.appsignal.com/nodejs/3.x/migration-guide <Note> πŸ›Ÿ Don't hesitate to [contact us](mailto:support@appsignal.com) if you run into any issues while upgrading your application's AppSignal for Node.js package. We're here to help! </Note> This documentation lists the changes between the 2.x and 3.x releases of AppSignal's Node.js package. If you are upgrading from 2.x to 3.x you will need to modify your integration to work successfully. If you run into any issues while upgrading your application, be sure to [contact us](mailto:support@appsignal.com) for support. ## Installing 3.x To install AppSignal for Node.js 3.x run the following command in your application's root directory. #### npm <CodeGroup> ```bash Bash theme={null} npm install @appsignal/nodejs ``` </CodeGroup> ## AppSignal Client When upgrading from 2.x to 3.x, you need to change how your application initializes and accesses the AppSignal client. ### Initialize AppSignal Client To initialize the AppSignal client and export it, you will need to create a new `appsignal.cjs` file, like in the example below: <CodeGroup> ```javascript Node.js theme={null} // appsignal.cjs const { Appsignal } = require("@appsignal/nodejs"); const appsignal = new Appsignal({ active: true, name: "Your app name", }); ``` </CodeGroup> You will need to require (`--require ./appsignal.cjs`) your `appsignal.cjs` file when starting your application. For example, in your application's `package.json` file, like in the example below: #### Javascript <CodeGroup> ```json JSON theme={null} "scripts": { "server": "node --require ./appsignal.cjs index.js" } ``` </CodeGroup> ### Access AppSignal Client In 3.x the AppSignal client is accessed from the globally exported `Appsignal.client` object. The below examples show how to do this within the context of a [custom metrics counter](/metrics/custom#counter). #### 2.x <CodeGroup> ```javascript Node.js theme={null} import { appsignal } from "./appsignal"; // or: const appsignal = new Appsignal({...}); const meter = appsignal.metrics(); meter.incrementCounter("slow_queries", 1); ``` </CodeGroup> #### 3.x <CodeGroup> ```javascript Node.js theme={null} import { Appsignal } from "@appsignal/nodejs"; // or: const { Appsignal } = require("@appsignal/nodejs"); const meter = Appsignal.client.metrics(); meter.incrementCounter("slow_queries", 1); ``` </CodeGroup> ## Integrations <Tip> Express and Next.js require an [Error Handler](/nodejs/3.x/integrations/express#error-handler). </Tip> AppSignal for Node.js 3.x supports all 2.x integrations out of the box. This means the packages for each integration no longer need to be installed. When moving to 3.x from 2.x you will need to remove any AppSignal integration packages installed for your application. ### Uninstall Integrations <Warning> The 2.x integrations are not compatible with the 3.x Node.js integration. You must follow the migration steps outlined below to use Node.js integrations. </Warning> To take advantage of the AppSignal for Node.js 3.x out-of-the-box integration support, you'll first need to "undo" the integration installations that were necessary in the 2.x version. #### Remove AppSignal Package Dependent Code <Tip> The examples below are illustrative and based on AppSignal's 2.x and 3.x integration documentation. The code in your application may differ from the examples in this documentation. </Tip> * [Apollo Server](#remove-apollo-server-integration) * [Express](#remove-express-integration) * [Koa.js](#remove-koajs-integration) * [Next.js](#remove-nextjs-integration) **Don't forget to [remove/uninstall the AppSignal integration package](#remove-integration-package)**. ### Remove Apollo Server Integration <Warning> The 2.x `@appsignal/apollo-server` package is not compatible with the 3.x Node.js integration. You must follow the migration steps outlined below if you wish to use Apollo Server with our 3.x integration. </Warning> Remove the 2.x initialization of the Appsignal Apollo Server package and plugin from your application, and replace it with the 3.x installation instructions. Your Apollo application will be instrumented automatically. #### 2.x <CodeGroup> ```javascript Node.js theme={null} import { createApolloPlugin } from "@appsignal/apollo-server"; import { ApolloServer, gql } from "apollo-server-express"; // or: const { createApolloPlugin } = require("@appsignal/apollo-server"); // or: const { ApolloServer, gql } = require("apollo-server-express"); const server = new ApolloServer({ /* ... */ plugins: [createApolloPlugin(appsignal)], }); ``` </CodeGroup> #### 3.x Apollo Server is instrumented automatically by the AppSignal for Node.js package. [Read 3.x GraphQL Integration Documentation](/nodejs/3.x/integrations/graphql) Once you've modified your integration code, you need to [remove the Apollo AppSignal package](#remove-apollo-server-integration) from your application. ### Remove Express Integration <Warning> The 2.x `@appsignal/express` package is not compatible with the 3.x Node.js integration. You must follow the migration steps outlined below if you wish to use express with our 3.x integration. </Warning> Remove the 2.x initialization of AppSignal Express package and middleware from your application, and replace it with the 3.x installation instructions. #### 2.x <CodeGroup> ```javascript Node.js theme={null} import express from "express"; // or: const express = require("express"); const { expressMiddleware, expressErrorHandler, } = require("@appsignal/express"); // your app code goes here // add this after all other express middleware, but before any routes app.use(expressMiddleware(appsignal)); // add this after all routes, but before any other error handlers app.use(expressErrorHandler(appsignal)); ``` </CodeGroup> #### 3.x <CodeGroup> ```javascript Node.js theme={null} import { expressErrorHandler } from "@appsignal/nodejs"; // or: const { expressErrorHandler } = require("@appsignal/nodejs"); const app = express(); // your app code goes here // add this after all routes, but before any other error handlers app.use(expressErrorHandler()); ``` </CodeGroup> [Read 3.x Express Integration Documentation](/nodejs/3.x/integrations/express) Once you've modified your integration code, you need to [remove the Appsignal Express package](#remove-express-integration) from your application. ### Remove Koa.js Integration <Warning> The 2.x `@appsignal/koa` package is not compatible with the 3.x Node.js integration. You must follow the migration steps outlined below if you wish to use Koa.js with our 3.x integration. </Warning> Remove the 2.x initialization of the Appsignal Koa package and instrumentation from your application. #### 2.x <CodeGroup> ```javascript Node.js theme={null} import appsignalKoa from "@appsignal/koa"; // or: const appsignalKoa = require("@appsignal/koa"); appsignal.instrument(appsignalKoa); ``` </CodeGroup> #### 3.x Koa.js is instrumented automatically by the AppSignal for Node.js package. [Read 3.x Koa.js Integration Documentation](/nodejs/3.x/integrations/koajs) Once you've modified your integration code, you need to [remove the Koa.js package](#remove-koajs-integration) from your application. ### Remove Next.js Integration <Warning> The 2.x `@appsignal/nextjs` package is not compatible with the 3.x Node.js integration. You must follow the migration steps outlined below if you wish to use Next.js with our 3.x integration. </Warning> The "Web Vitals Reporting" feature has been deprecated and is no longer available on AppSignal for Node.js 3.x. #### 2.x <CodeGroup> ```javascript Node.js theme={null} import { getRequestHandler } from "@appsignal/nextjs"; // or: const { getRequestHandler } = require("@appsignal/nextjs"); ``` </CodeGroup> #### 3.x Next.js is instrumented automatically by the AppSignal for Node.js package. [Read 3.x Next.js Integration Documentation](/nodejs/3.x/integrations/nextjs) ### Remove Integration Package Once the imports and code dependent on those imports are removed, you need to uninstall the integration package. This can be done by running `npm uninstall`, like in the example below. ```bash Bash theme={null} npm uninstall @appsignal/express ``` The `npm uninstall` commands will remove package dependencies and update your application's `package.json` and npm's `package-lock.json` file. Replace `@appsignal/express` in the example above with the integration package name you are removing. #### AppSignal Integration Package Names | Integration | Package Name | | ------------- | -------------------------- | | Apollo Server | `@appsignal/apollo-server` | | Express | `@appsignal/express` | | Koa.js | `@appsignal/koa` | | Next.js | `@appsignal/nextjs` | ## The Tracer Object There's no longer a custom AppSignal tracer object. OpenTelemetry exposes a tracer provider which allows you to create new spans. #### 2.x: <CodeGroup> ```javascript Node.js theme={null} const tracer = appsignal.tracer(); ``` </CodeGroup> #### 3.x: <CodeGroup> ```javascript Node.js theme={null} import { trace } from "@opentelemetry/api"; // or: const { trace } = require("@opentelemetry/api"); const tracer = trace.getTracer("my-interesting-app"); ``` </CodeGroup> [Read more about tracers in the 3.x instrumentation documentation.](/nodejs/3.x/instrumentation/instrumentation) ## Spans There's no longer a custom AppSignal span object. AppSignal's tracer functions, such as `rootSpan()`, `createSpan()`, `currentSpan()` and `withSpan()` functions are no longer available. Spans must be created by calling the `startActiveSpan` method on a tracer object. New spans are automatically the children of the span they were created in. #### 2.x: <CodeGroup> ```javascript Node.js theme={null} tracer.withSpan(tracer.createSpan(), async (span) => { span.setName("your span's name"); // logic to trace here }); ``` </CodeGroup> #### 3.x: <CodeGroup> ```javascript Node.js theme={null} tracer.startActiveSpan("your span's name", async (span) => { /// logic to trace here span.end(); }); ``` </CodeGroup> [Read more about spans in the 3.x instrumentation documentation.](/nodejs/3.x/instrumentation/instrumentation) ### Span Attribute Helpers The helper functions used to set span attributes have also changed. `setSQL` has been replaced with `setBody`, `set` has been renamed to `setTag`, and additional helper functions have been added. `setName` has been removed, as spans must be given a name when they are created. #### 2.x <CodeGroup> ```javascript Node.js theme={null} const span = tracer.currentSpan(); span.setCategory("query.sql"); span.setSQL("SELECT * FROM users"); ``` </CodeGroup> #### 3.x <CodeGroup> ```javascript JavaScript theme={null} setCategory("query.sql"); setSQL("SELECT * FROM users"); ``` </CodeGroup> [Read more about spans attribute helpers in the 3.x instrumentation documentation.](/nodejs/3.x/instrumentation/instrumentation#helpers) ## Exception Handling Tracer and span objects are no longer needed when using `setError()` and `sendError()`. #### 2.x <CodeGroup> ```javascript Node.js theme={null} tracer.setError(err); tracer.sendError(err, (span) => { span.setName("daily.task"); span.set("user_id", user_id); }); ``` </CodeGroup> #### 3.x In `sendError()`, [helpers](/nodejs/3.x/instrumentation/instrumentation#helpers) can be used to add additional data to the error span. <CodeGroup> ```javascript Node.js theme={null} import { setError, sendError } from "@appsignal/nodejs"; // or: const { setError, sendError } = require("@appsignal/nodejs"); setError(err); sendError(err, () => { setTag("user_id", user_id); }); ``` </CodeGroup> [Read more about exception handling in the 3.x exception handling documentation](/nodejs/3.x/instrumentation/exception-handling) # OpenTelemetry Source: https://docs.appsignal.com/opentelemetry AppSignal relies on OpenTelemetry to provide support for languages like Go, Java, and PHP, and tools and services that export data using OpenTelemetry. We are continuously improving our support for the OpenTelemetry protocol, extending our monitoring capabilities to more programming languages. This will allow you to send tracing and metric data to AppSignal directly via OpenTelemetry. ## We want your feedback! Our OpenTelemetry support is relatively new and we haven't tested it yet with all the different setups out there. Some features may not work with OpenTelemetry data yet. If you encounter any issues or have suggestions for improvement, please contact support or join our Discord server. <CardGroup> <Card title="Contact support" icon="envelope" href="mailto:support@appsignal.com?subject=OpenTelemetry" /> <Card title="Join our Discord" icon="discord" href="https://discord.gg/VreYMePw9e" /> </CardGroup> ## Setting up OpenTelemetry Follow the installation instructions in the next step to set up OpenTelemetry in your application and report data to AppSignal. # OpenTelemetry Configuration Source: https://docs.appsignal.com/opentelemetry/configuration In this documentation, we'll explain how to configure OpenTelemetry in your application, the available options, and the minimal configuration required. The configuration options for the OpenTelemetry resource, set by the OpenTelemetry exporter, can be found on the [configuration options page](/opentelemetry/configuration/options). To configure the AppSignal collector, the program used to send data to AppSignal, please refer to the [collector's configuration documentation](/collector/configuration). # OpenTelemetry config options Source: https://docs.appsignal.com/opentelemetry/configuration/options AppSignal can be configured through OpenTelemetry resource attributes. On this page we'll describe how to configure resource attributes and which attributes can be set. ## Configuring OpenTelemetry resource attributes You can configure OpenTelemetry to send data to AppSignal using resource attributes. Resource attributes are attributes that apply to every trace reported from the application using OpenTelemetry. You can configure resource attributes in your OpenTelemetry configuration file, this is also where you need to set up the OpenTelemetry exporter to send data to the [AppSignal collector](/opentelemetry/installation). <CodeGroup> ```go Go theme={null} import ( // Other imports .... "go.opentelemetry.io/otel/sdk/resource" semconv "go.opentelemetry.io/otel/semconv/v1.27.0" sdktrace "go.opentelemetry.io/otel/sdk/trace" ) res := resource.NewSchemaless( // Add resource attributes here semconv.ServiceNameKey.String("My service name"), resource.WithAttributes(attribute.String("appsignal.config.name", "My app name")), ) tp := sdktrace.NewTracerProvider( // Other .With... calls sdktrace.WithResource(res), ) ``` </CodeGroup> ## App name * Attribute name: `appsignal.config.name` * Or as request header: `Appsignal-Config-Name` * Type: String * Required: Yes Name of your application as it should be displayed on AppSignal.com. <CodeGroup> ```python Python theme={null} attributes = { # Add this line to the resource attributes "appsignal.config.name": "My awesome app", } resource = Resource(attributes=attributes) ``` ```go Go theme={null} import ( "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/sdk/resource" ) res := resource.NewWithAttributes( // Other resource attributes resource.WithAttributes(attribute.String("appsignal.config.name", "My awesome app")), ) ``` </CodeGroup> ## App environment * Attribute name: `appsignal.config.environment` * Or as request header: `Appsignal-Config-Environment` * Type: String * Required: Yes The environment of the application as it should be displayed on AppSignal.com. <CodeGroup> ```python Python theme={null} attributes = { # Add this line to the resource attributes "appsignal.config.environment": "staging", } resource = Resource(attributes=attributes) ``` ```go Go theme={null} import ( "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/sdk/resource" ) res := resource.NewWithAttributes( // Other resource attributes resource.WithAttributes(attribute.String("appsignal.config.environment", "production")), ) ``` </CodeGroup> ## Push API key * Attribute name: `appsignal.config.push_api_key` * Or as request header: `Appsignal-Config-PushApiKey` * Type: String * Required: Yes The organization-level authentication key to authenticate with our Push API. For detailed information about the [AppSignal Push API key](/appsignal/terminology#push-api-key), check out our terminology documentation. <CodeGroup> ```python Python theme={null} attributes = { # Add this line to the resource attributes "appsignal.config.push_api_key": "00000000-0000-0000-0000-000000000000", } resource = Resource(attributes=attributes) ``` ```go Go theme={null} import ( "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/sdk/resource" ) res := resource.NewWithAttributes( // Other resource attributes resource.WithAttributes(attribute.String("appsignal.config.push_api_key", "00000000-0000-0000-0000-000000000000")), ) ``` </CodeGroup> ## App revision * Attribute name: `appsignal.config.revision` * Or as request header: `Appsignal-Config-Revision` * Type: String * Required: Yes To report new deploys of OpenTelemetry applications, you can use [Deploy Markers](/application/markers/deploy-markers). Deploy markers can be configured with the revision resource attribute. The value of this attribute will be used to identify new deploys. It needs to be unique per deploy to pick up new deploys. We recommend using Git commit SHAs or a tag in your SCM. This can be used in combination with our [backtrace links](/application/backtrace-links) to directly link from AppSignal back to the source code on platforms like GitHub and GitLab. <CodeGroup> ```python Python theme={null} import subprocess attributes = { # ... } try: revision = subprocess.check_output("git rev-parse --short HEAD", shell=True, text=True).strip() attributes["appsignal.config.revision"] = revision except subprocess.CalledProcessError: pass resource = Resource(attributes=attributes) ``` ```go Go theme={null} import ( "os/exec" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/sdk/resource" ) var revision string cmd := exec.Command("git", "rev-parse", "--short", "HEAD") output, err := cmd.Output() if err != nil { revision = "unknown" } else { revision = strings.TrimSpace(string(output)) } res := resource.NewWithAttributes( // Other resource attributes resource.WithAttributes(attribute.String("appsignal.config.revision", revision)), ) ``` </CodeGroup> ## Language integration * Attribute name: `appsignal.config.language_integration` * Or as request header: `Appsignal-Config-LanguageIntegration` * Type: String * Required: Yes AppSignal uses the `language_integration` resource attribute to detect the language of a trace and correctly parse exception backtraces. To set this option, specify the language name in lowercase format, e.g. "python", "rust", "ruby", "elixir", "go" and "nodejs". <CodeGroup> ```python Python theme={null} attributes = { # Add this line to the resource attributes "appsignal.config.language_integration": "python", } resource = Resource(attributes=attributes) ``` ```go Go theme={null} import ( "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/sdk/resource" ) res := resource.NewWithAttributes( // Other resource attributes resource.WithAttributes(attribute.String("appsignal.config.language_integration", "go")), ) ``` </CodeGroup> ## OTP app name * Attribute name: `appsignal.config.otp_app` * Type: String * Required: Yes, for Elixir apps AppSignal uses the `appsignal.config.otp_app` resource attribute to detect which backtrace lines from errors belong to the application. You can find the OTP app name for your application by calling `IO.inspect(:application.get_application())` in your application and checking the output. <CodeGroup> ```elixir Elixir theme={null} config :opentelemetry, resource: [ {"appsignal.config.otp_app", "OTP app name"}, # And other resource attributes ] ``` </CodeGroup> ## Service name * Attribute name: `service.name` * Or as request header: `OpenTelemetry-ServiceName` * Type: String * Required: Yes The `service.name` resource attribute helps AppSignal recognize different services for traces and groups the traces automatically in a namespace based on the service name. Choose a name that fits your application, like "Web server", "Background worker", "Email service", "Authentication service", etc. <CodeGroup> ```python Python theme={null} import socket attributes = { # Add this line to the resource attributes "service.name": "My service name", } resource = Resource(attributes=attributes) ``` ```go Go theme={null} import ( "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/sdk/resource" ) res := resource.NewWithAttributes( // Other resource attributes resource.WithAttributes(attribute.String("service.name", "My service name")), ) ``` </CodeGroup> ## Hostname * Attribute name: `host.name` * Or as request header: `OpenTelemetry-HostName` * Type: String * Required: Yes The `host.name` resource attribute helps AppSignal recognize different hosts for traces and tag the traces automatically with the hostname. <CodeGroup> ```python Python theme={null} import socket attributes = { # Add this line to the resource attributes "host.name": socket.gethostname(), } resource = Resource(attributes=attributes) ``` ```go Go theme={null} import ( "os" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/sdk/resource" ) hostname, err := os.Hostname() if err != nil { hostname = "unknown" } res := resource.NewWithAttributes( // Other resource attributes resource.WithAttributes(attribute.String("host.name", hostname)), ) ``` </CodeGroup> ## App path * Attribute name: `appsignal.config.app_path` * Type: String * Required: No The location of the app on the host's file system. The `app_path` resource attribute helps AppSignal clean up backtraces by stripping away the absolute app path of backtrace lines. This way only paths within the context of the project directory is shown. This makes our [Backtrace links](/application/backtrace-links) feature possible. <CodeGroup> ```python Python theme={null} import os attributes = { # Add this line to the resource attributes "appsignal.config.app_path": os.getcwd() } resource = Resource(attributes=attributes) ``` ```go Go theme={null} import ( "os" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/sdk/resource" ) res := resource.NewWithAttributes( // Other resource attributes resource.WithAttributes(attribute.String("appsignal.config.app_path", os.Getenv("PWD"))), ) ``` </CodeGroup> ## Filter attributes * Attribute name: `appsignal.config.filter_attributes` * Type: Array * Required: No The `filter_attributes` resource attribute allows you to filter out specific attributes from being reported to AppSignal. This can be useful to filter out sensitive or non-relevant information from being reported. If an attribute is filtered out this way, it will not show up in the interface at all. <CodeGroup> ```python Python theme={null} attributes = { # Add this line to the resource attributes "appsignal.config.filter_attributes": ["my.secret.attribute", "some.opentelemetry.attribute"], } resource = Resource(attributes=attributes) ``` ```go Go theme={null} import ( "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/sdk/resource" ) res := resource.NewWithAttributes( // Other resource attributes attribute.StringSlice("appsignal.config.filter_attributes", []string{"my.secret.attribute", "some.opentelemetry.attribute"}), ) ``` </CodeGroup> ## Filter function parameters * Attribute name: `appsignal.config.filter_function_parameters` * Type: Array * Default value: *Empty* * Required: No The `filter_function_parameters` resource attribute allows you to filter out any function parameters set in the [`appsignal.function.parameters` span attribute](/opentelemetry/custom-instrumentation/attributes#function-parameters). In the example below, values for the keys listed in the `filter_function_parameters` config option are replaced with `[FILTERED]`. <CodeGroup> ```python Python theme={null} # Configure the exporter's resource like so: attributes = { # Add this line to the resource attributes "appsignal.config.filter_function_parameters": ["password", "cvv"], } resource = Resource(attributes=attributes) # Rest of the exporter config... # Then in the trace, set the function parameters span attribute import json from opentelemetry import trace tracer = trace.get_tracer(__name__) with tracer.start_as_current_span("something.custom") as span: span.set_attribute("appsignal.function.parameters", json.dumps({ "password": "super secret", "test_param": "test value", "nested": { "password": "super secret nested", "test_param": "test value", } })) ``` ```go Go theme={null} // Configure the exporter's resource like so: import ( "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" "go.opentelemetry.io/otel/sdk/resource" ) res := resource.NewWithAttributes( // Other resource attributes attribute.StringSlice("appsignal.config.filter_function_parameters", []string{"password", "cvv"}), ) // Rest of the exporter config... // Then in the trace, set the function parameters span attribute import ( "encoding/json" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" ) // The context needs contain the active span you plan to extract // Like `c.Request.Context()` for gin apps ctx := context.TODO() span := trace.SpanFromContext(ctx) params := map[string]interface{}{ "password": "super secret", "test_param": "test value", "nested": map[string]interface{}{ "password": "super secret", "test_param": "test value", }, } json, _ := json.Marshal(params) span.SetAttributes(attribute.String("appsignal.function.parameters", string(json))) ``` </CodeGroup> ## Filter request query parameters * Attribute name: `appsignal.config.filter_request_query_parameters` * Type: Array * Default value: *Empty* * Required: No The `filter_request_query_parameters` resource attribute allows you to filter out any request query parameters set in the [`appsignal.request.query_parameters` span attribute](/opentelemetry/custom-instrumentation/attributes#request-query-parameters). In the example below, values for the keys listed in the `filter_request_query_parameters` config option are replaced with `[FILTERED]`. <CodeGroup> ```python Python theme={null} # Configure the exporter's resource like so: attributes = { # Add this line to the resource attributes "appsignal.config.filter_request_query_parameters": ["password", "cvv"], } resource = Resource(attributes=attributes) # Rest of the exporter config... # Then in the trace, set the query parameters span attribute import json from opentelemetry import trace tracer = trace.get_tracer(__name__) with tracer.start_as_current_span("something.custom") as span: span.set_attribute("appsignal.request.query_parameters", json.dumps({ "password": "super secret", "test_param": "test value" })) ``` ```go Go theme={null} // Configure the exporter's resource like so: import ( "encoding/json" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" "go.opentelemetry.io/otel/sdk/resource" ) res := resource.NewWithAttributes( // Other resource attributes attribute.StringSlice("appsignal.config.filter_request_query_parameters", []string{"password", "cvv"}), ) // Rest of the exporter config... // Then in the trace, set the query parameters span attribute import ( "encoding/json" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" ) // The context needs contain the active span you plan to extract // Like `c.Request.Context()` for gin apps ctx := context.TODO() span := trace.SpanFromContext(ctx) params := map[string]interface{}{ "password": "super secret", "test_param": "test value", "nested": map[string]interface{}{ "password": "super secret", "test_param": "test value", }, } json, _ := json.Marshal(params) span.SetAttributes(attribute.String("appsignal.request.query_parameters", string(json))) ``` </CodeGroup> ## Filter request payload * Attribute name: `appsignal.config.filter_request_payload` * Type: Array * Default value: *Empty* * Required: No The `filter_request_payload` resource attribute allows you to filter out any request payload data set in the [`appsignal.request.payload` span attribute](/opentelemetry/custom-instrumentation/attributes#request-payload). In the example below, values for the keys listed in the `filter_request_payload` config option are replaced with `[FILTERED]`. <CodeGroup> ```python Python theme={null} # Configure the exporter's resource like so: attributes = { # Add this line to the resource attributes "appsignal.config.filter_request_payload": ["password", "cvv"], } resource = Resource(attributes=attributes) # Rest of the exporter config... # Then in the trace, set the request payload span attribute import json from opentelemetry import trace tracer = trace.get_tracer(__name__) with tracer.start_as_current_span("something.custom") as span: span.set_attribute("appsignal.request.payload", json.dumps({ "password": "super secret", "test_param": "test value", "nested": { "password": "super secret nested", "test_param": "test value", } })) ``` ```go Go theme={null} // Configure the exporter's resource like so: import ( "encoding/json" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" "go.opentelemetry.io/otel/sdk/resource" ) res := resource.NewWithAttributes( // Other resource attributes attribute.StringSlice("appsignal.config.filter_request_payload", []string{"password", "cvv"}), ) // Rest of the exporter config... // Then in the trace, set the function parameters span attribute import ( "encoding/json" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" ) // The context needs contain the active span you plan to extract // Like `c.Request.Context()` for gin apps ctx := context.TODO() span := trace.SpanFromContext(ctx) params := map[string]interface{}{ "password": "super secret", "test_param": "test value", "nested": map[string]interface{}{ "password": "super secret", "test_param": "test value", }, } json, _ := json.Marshal(params) span.SetAttributes(attribute.String("appsignal.request.payload", string(json))) ``` </CodeGroup> ## Filter request session data * Attribute name: `appsignal.config.filter_request_session_data` * Type: Array * Default value: *Empty* * Required: No The `filter_request_session_data` resource attribute allows you to filter out any request session data set in the [`appsignal.request.session_data` span attribute](/opentelemetry/custom-instrumentation/attributes#request-session-data). In the example below, values for the keys listed in the `filter_request_session_data` config option are replaced with `[FILTERED]`. <CodeGroup> ```python Python theme={null} # Configure the exporter's resource like so: attributes = { # Add this line to the resource attributes "appsignal.config.filter_request_session_data": ["password", "cvv"], } resource = Resource(attributes=attributes) # Rest of the exporter config... # Then in the trace, set the session data span attribute import json from opentelemetry import trace tracer = trace.get_tracer(__name__) with tracer.start_as_current_span("something.custom") as span: span.set_attribute("appsignal.request.session_data", json.dumps({ "password": "super secret", "test_param": "test value", "nested": { "password": "super secret nested", "test_param": "test value", } })) ``` ```go Go theme={null} // Configure the exporter's resource like so: import ( "encoding/json" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" "go.opentelemetry.io/otel/sdk/resource" ) res := resource.NewWithAttributes( // Other resource attributes attribute.StringSlice("appsignal.config.filter_session_data", []string{"password", "cvv"}), ) // Rest of the exporter config... // Then in the trace, set the session data parameters span attribute import ( "encoding/json" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" ) // The context needs contain the active span you plan to extract // Like `c.Request.Context()` for gin apps ctx := context.TODO() span := trace.SpanFromContext(ctx) sessionData := map[string]interface{}{ "password": "super secret", "test_param": "test value", "nested": map[string]interface{}{ "password": "super secret", "test_param": "test value", }, } json, _ := json.Marshal(sessionData) span.SetAttributes(attribute.String("appsignal.request.session_data", string(json))) ``` </CodeGroup> ## Ignore actions * Attribute name: `appsignal.config.ignore_actions` * Type: Array of Strings * Required: No The `ignore_actions` resource attribute allows you to ignore specific actions from being reported to AppSignal. This can be useful to ignore health check endpoints or other actions that you don't want to monitor. <CodeGroup> ```python Python theme={null} attributes = { # Add this line to the resource attributes "appsignal.config.ignore_actions": ["GET /health_check", "POST /ping"], } resource = Resource(attributes=attributes) ``` ```go Go theme={null} import ( "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/sdk/resource" ) res := resource.NewWithAttributes( // Other resource attributes attribute.StringSlice("appsignal.config.ignore_actions", []string{"GET /heath_check", "POST /ping"}), ) ``` </CodeGroup> ## Ignore errors * Attribute name: `appsignal.config.ignore_errors` * Type: Array of Strings * Required: No The `ignore_errors` resource attribute allows you to ignore specific errors from being reported to AppSignal. This can be useful to ignore expected errors or errors that can't be solved. <CodeGroup> ```python Python theme={null} attributes = { # Add this line to the resource attributes "appsignal.config.ignore_errors": ["MyCustomError", "ExpectedError"], } resource = Resource(attributes=attributes) ``` ```go Go theme={null} import ( "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/sdk/resource" ) res := resource.NewWithAttributes( // Other resource attributes attribute.StringSlice("appsignal.config.ignore_errors", []string{"MyCustomError", "ExpectedError"}), ) ``` </CodeGroup> ## Ignore namespaces * Attribute name: `appsignal.config.ignore_namespaces` * Type: Array of Strings * Required: No The `ignore_namespaces` resource attribute allows you to ignore specific namespaces from being reported to AppSignal. This can be useful to ignore specific parts of your application from being monitored. <CodeGroup> ```python Python theme={null} attributes = { # Add this line to the resource attributes "appsignal.config.ignore_namespaces": ["admin" ,"secret"], } resource = Resource(attributes=attributes) ``` ```go Go theme={null} import ( "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/sdk/resource" ) res := resource.NewWithAttributes( // Other resource attributes attribute.StringSlice("appsignal.config.ignore_namespaces", []string{"admin", "secret"}), ) ``` </CodeGroup> ## Response headers * Attribute name: `appsignal.config.response_headers` * Type: Array of Strings * Default value: `["content-length", "accept", "accept-charset", "accept-encoding", "accept-language", "cache-control", "connection", "range", "host"]` * Required: No Configure which response headers to include when a request is made by an HTTP client. This option is an allowlist. It only includes the headers that are configured. If the list is empty, no headers are included. The response headers are read from the `http.response.header.<key>` [OpenTelemetry span attributes](https://opentelemetry.io/docs/specs/semconv/http/http-spans/), where `<key>` is the normalized header name (lowercase). To not set any headers, explicitly set the resource attribute value to an empty array. <CodeGroup> ```python Python theme={null} attributes = { # Only send these specific headers "appsignal.config.response_headers": ["accept", "request_method", "content_length"] # Do not send any headers "appsignal.config.response_headers": [] } resource = Resource(attributes=attributes) ``` ```go Go theme={null} res := resource.NewWithAttributes( // Only send these specific headers attribute.StringSlice("appsignal.config.response_headers", []string{"accept", "request_method", "content_length"}), // Do not send any headers attribute.StringSlice("appsignal.config.response_headers", []string{}), ) ``` </CodeGroup> ## Request headers * Attribute name: `appsignal.config.request_headers` * Type: Array of Strings * Default value: `["content-length", "accept", "accept-charset", "accept-encoding", "accept-language", "cache-control", "connection", "range", "host"]` * Required: No Configure which request headers to include when a request is made to an HTTP server. This option is an allowlist. It only includes the headers that are configured. If the list is empty, no headers are included. The request headers are read from the `http.request.header.<key>` [OpenTelemetry span attributes](https://opentelemetry.io/docs/specs/semconv/http/http-spans/), where `<key>` is the normalized header name (lowercase). To not set any headers, explicitly set the resource attribute value to an empty array. <CodeGroup> ```python Python theme={null} attributes = { # Only send these specific headers "appsignal.config.request_headers": ["accept", "request_method", "content_length"] # Do not send any headers "appsignal.config.response_headers": [] } resource = Resource(attributes=attributes) ``` ```go Go theme={null} res := resource.NewWithAttributes( // Only send these specific headers attribute.StringSlice("appsignal.config.request_headers", []string{"accept", "request_method", "content_length"}), // Do not send any headers attribute.StringSlice("appsignal.config.request_headers", []string{}), ) ``` </CodeGroup> ## Send function parameters * Attribute name: `appsignal.config.send_function_parameters` * Type: Boolean * Default value: `true` * Required: No Configure whether to include function parameters in traces. If set to `false` no such data is sent to our servers. These values are set with the [`appsignal.function.parameters` span attribute](/opentelemetry/custom-instrumentation/attributes#function-parameters). <CodeGroup> ```python Python theme={null} attributes = { # Add this line to the resource attributes "appsignal.config.send_function_parameters": false } resource = Resource(attributes=attributes) ``` ```go Go theme={null} res := resource.NewWithAttributes( // Add this line to the resource attributes attribute.Bool("appsignal.config.send_function_parameters", false), ) ``` </CodeGroup> ## Send request query parameter * Attribute name: `appsignal.config.send_request_query_parameters` * Type: Boolean * Default value: `true` * Required: No Configure whether to include request query parameters in traces. If set to `false` no such data is sent to our servers. These values are set with the [`appsignal.request.query_parameters` span attribute](/opentelemetry/custom-instrumentation/attributes#request-query-parameters). For more information please read about [request parameter filtering](/application/parameter-filtering). <CodeGroup> ```python Python theme={null} attributes = { # Add this line to the resource attributes "appsignal.config.send_request_query_parameters": false } resource = Resource(attributes=attributes) ``` ```go Go theme={null} res := resource.NewWithAttributes( // Add this line to the resource attributes attribute.Bool("appsignal.config.send_request_query_parameters", false), ) ``` </CodeGroup> ## Send request payload * Attribute name: `appsignal.config.send_request_payload` * Type: Boolean * Default value: `true` * Required: No Configure whether to send request payload data in traces. If set to `false` no such data is sent to our servers. These values are set with the [`appsignal.request.payload` span attribute](/opentelemetry/custom-instrumentation/attributes#request-payload). <CodeGroup> ```python Python theme={null} attributes = { # Add this line to the resource attributes "appsignal.config.send_request_payload": false } resource = Resource(attributes=attributes) ``` ```go Go theme={null} res := resource.NewWithAttributes( // Add this line to the resource attributes attribute.Bool("appsignal.config.send_request_payload", false), ) ``` </CodeGroup> ## Send request session data * Attribute name: `appsignal.config.send_request_session_data` * Type: Boolean * Default value: `true` * Required: No Configure whether to send request session data in traces. If set to `false` no such data is sent to our servers. These values are set with the [`appsignal.request.session_data` span attribute](/opentelemetry/custom-instrumentation/attributes#request-session-data). <CodeGroup> ```python Python theme={null} attributes = { # Add this line to the resource attributes "appsignal.config.send_request_session_data": false } resource = Resource(attributes=attributes) ``` ```go Go theme={null} res := resource.NewWithAttributes( // Add this line to the resource attributes attribute.Bool("appsignal.config.send_session_data", false), ) ``` </CodeGroup> # Custom Instrumentation Source: https://docs.appsignal.com/opentelemetry/custom-instrumentation AppSignal is compatible with OpenTelemetry instrumentation packages. This does not always include the information you need to debug issues. For more fine-grained reporting, you can add custom instrumentation. We support [OpenTelemetry tracing](https://opentelemetry.io/docs/) as laid out in the OpenTelemetry documentation. It's possible to add more data to span using OpenTelemetry span attributes. There are also AppSignal span attributes that can change how traces are grouped and some attributes that allow for filtering out sensitive data. The AppSignal span attributes are described in more detail in our [OpenTelemetry Custom Instrumentation Attributes](/opentelemetry/custom-instrumentation/attributes) section. # OpenTelemetry instrumentation attributes Source: https://docs.appsignal.com/opentelemetry/custom-instrumentation/attributes AppSignal supports multiple OpenTelemetry language integrations. However, the data model may not always align perfectly, which can affect how OpenTelemetry data is displayed in the AppSignal interface. By using the attributes listed on this page, you can customize the appearance of trace and span data. <Warning> πŸ” Do not send <strong>Personal Identifiable Information (PII)</strong> to AppSignal. Filter PII (e.g., names, emails) and use an ID, hash, or pseudonymized identifier instead. <br /> <br /> For <strong>HIPAA-covered entities</strong>, more info on signing a Business Associate Agreement (BAA) is available in our <a href="/support/business-add-ons">Business Add-Ons documentation</a>. </Warning> ## Accessing a span <Tabs> <Tab title="Python"> When customizing the trace or span, first import the OpenTelemetry trace module in the file you want to customize the reported trace data. <CodeGroup> ```python Python theme={null} from opentelemetry import trace ``` </CodeGroup> Using that trace module, create a new span: <CodeGroup> ```python Python theme={null} tracer = trace.get_tracer(__name__) with tracer.start_as_current_span("Span name") as span: # Set attribute values span.set_attribute("attribute name", "attribute value") ``` </CodeGroup> Or fetch the current active one: <CodeGroup> ```python Python theme={null} span = trace.get_current_span() # Set attribute values span.set_attribute("attribute name", "attribute value") ``` </CodeGroup> </Tab> <Tab title="Go (golang)"> When customizing the trace or span, first import the OpenTelemetry trace module in the file you want to customize the reported trace data. <CodeGroup> ```go Go theme={null} import ( "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" ) ``` </CodeGroup> Using that trace module, create a new span: <CodeGroup> ```go Go theme={null} var tracer = otel.Tracer("my-tracer-name") func httpHandler(w http.ResponseWriter, r *http.Request) { ctx, span := tracer.Start(r.Context(), "hello-span") defer span.End() // Set attributes } ``` </CodeGroup> *Note: In these examples we're relying on the context from the HTTP request, given by `r.Context()`.* *Receiving the context may be different in your application.* Or fetch the current active one: <CodeGroup> ```go Go theme={null} func httpHandler(w http.ResponseWriter, r *http.Request) { ctx := r.Context() span := trace.SpanFromContext(ctx) // Set attributes } ``` </CodeGroup> </Tab> </Tabs> ## AppSignal attributes ### Namespace <Tip> This attribute applies to the entire trace. It can be set on a child span, and does not need to be set on the uppermost parent span. This attribute can only be set once per trace. If it is set multiple times, only the attribute from one span in the trace is applied. </Tip> * Attribute name: `appsignal.namespace` * Value type: `String` [Group traces by namespace](/application/namespaces) for better organization in the AppSignal interface. Namespaces are grouped per OpenTelemetry service name with the format `<Service name>/<Namespace>`, e.g. "Web server/admin" or "Background worker/billing". This attribute allows you to configure the namespace part only. The default namespace for all traces is `<Service name>/default`. <CodeGroup> ```python Python theme={null} span.set_attribute("appsignal.namespace", "admin") ``` ```go Go theme={null} span.SetAttributes(attribute.String("appsignal.namespace", "admin")) ``` </CodeGroup> ### Root action name <Tip> This attribute applies to the entire trace. It can be set on a child span, and does not need to be set on the uppermost parent span. This attribute can only be set once per trace. If it is set multiple times, only the attribute from one span in the trace is applied. </Tip> * Attribute name: `appsignal.action_name` * Value type: `String` Set the action name of the trace that will be used to create incidents and group tracing on AppSignal.com. This will overwrite any automated mapping done by the AppSignal support for specific instrumentation. It is useful for traces that are not created by supported libraries. If your trace is grouped with other not named or poorly grouped traces, it may be missing this attribute. We aim to improve our automatic grouping over time, so [please let us know](mailto:support@appsignal.com?subject=OpenTelemetry%20feedback) when you find that this attribute is needed. <CodeGroup> ```python Python theme={null} span.set_attribute("appsignal.action_name", "ControllerName#action") ``` ```go Go theme={null} span.SetAttributes(attribute.String("appsignal.action_name", "ControllerName#action")) ``` </CodeGroup> ### Tags * Attribute name: `appsignal.tag.<tag_name>` * Value type: `String` [Tag traces](/application/tagging) to bring them to the front on the trace detail pages and filter traces in the AppSignal interface. Multiple tags can be set on spans in a trace. Tags can be added to any span in a trace on any level on the trace. You can use [link templates](https://docs.appsignal.com/application/link-templates.html) to link tags to a specific URL, such as a user profile or admin page. The tag attribute key is built up out of two parts, the `appsignal.tag` prefix, and the tag key. For the tag `user_id`, this becomes `appsignal.tag.user_id` as an attribute key. <CodeGroup> ```python Python theme={null} span.set_attribute("appsignal.tag.<tag_name>", "string") # Example format span.set_attribute("appsignal.tag.user_id", user.id) ``` ```go Go theme={null} span.SetAttributes(attribute.String("appsignal.tag.<tag_name>", "string")) // Example format span.SetAttributes(attribute.String("appsignal.tag.user_id", user.id)) ``` </CodeGroup> ### Function parameters <Tip> This attribute's value needs to be serialized to a JSON string. It does not support a Hash or object from the integration language directly and will be silently ignored. </Tip> * Attribute name: `appsignal.function.parameters` * Value type: JSON serialized object Report the parameters for a function call using this attribute. Use this to set parameters given to a background job, a task or function call you'd like to track. The values set in this span attribute can be filtered using the [`appsignal.config.filter_function_parameters` config option](/opentelemetry/configuration/options#filter-function-parameters). <CodeGroup> ```python Python theme={null} span.set_attribute("appsignal.function.parameters", json.dumps({ "param1": "value1", "param2": "value2" })) ``` ```go Go theme={null} import ( "encoding/json" ) params := map[string]interface{}{ "param1": "value1", "param2": "value2", "nested": map[string]interface{}{ "param3": "value3", "param4": "value4", }, } json, _ := json.Marshal(params) span.SetAttributes(attribute.String("appsignal.function.parameters", string(json))) ``` </CodeGroup> ### Response headers <Tip> This attribute's value needs to be serialized to a JSON string. It does not support a Hash or object from the integration language directly and will be silently ignored. </Tip> * Attribute name: `http.response.header.<key>` * Value type: Array of Strings Report the response's headers using an OpenTelemetry span attribute. This span attribute is also documented on the [OpenTelemetry HTTP span specification](https://opentelemetry.io/docs/specs/semconv/http/http-spans/). <CodeGroup> ```python Python theme={null} span.set_attribute("http.response.header.content-type", ["application/json"]) span.set_attribute("http.response.header.custom-header", ["abc", "def"]) ``` ```go Go theme={null} span.SetAttributes(attribute.StringSlice("http.response.header.content-type", []string{"application/json"})) span.SetAttributes(attribute.StringSlice("http.response.header.custom-header", []string{"abc", "def"})) ``` </CodeGroup> ### Request headers <Tip> This attribute's value needs to be serialized to a JSON string. It does not support a Hash or object from the integration language directly and will be silently ignored. </Tip> * Attribute name: `http.request.header.<key>` * Value type: Array of Strings Report the request's headers using an OpenTelemetry span attribute. This span attribute is also documented on the [OpenTelemetry HTTP span specification](https://opentelemetry.io/docs/specs/semconv/http/http-spans/). <CodeGroup> ```python Python theme={null} span.set_attribute("http.request.header.content-type", ["application/json"]) span.set_attribute("http.request.header.custom-header", ["abc", "def"]) ``` ```go Go theme={null} span.SetAttributes(attribute.StringSlice("http.request.header.content-type", []string{"application/json"})) span.SetAttributes(attribute.StringSlice("http.request.header.custom-header"), []string{"abc", "def"}) ``` </CodeGroup> ### Request query parameters <Tip> This attribute's value needs to be serialized to a JSON string. It does not support a Hash or object from the integration language directly and will be silently ignored. </Tip> * Attribute name: `appsignal.request.query_parameters` * Value type: JSON serialized object Report an incoming HTTP request's query parameters using this attribute. The values set in this span attribute can be filtered using the [`appsignal.config.filter_request_query_parameters` config option](/opentelemetry/configuration/options#filter-request-query-parameters). <CodeGroup> ```python Python theme={null} span.set_attribute("appsignal.request.query_parameters", json.dumps({ "category": "shoes", "filter": "color:blue" })) ``` ```go Go theme={null} import ( "encoding/json" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" ) params := map[string]interface{}{ "param1": "value1", "param2": "value2", "nested": map[string]interface{}{ "param3": "value3", "param4": "value4", }, } json, _ := json.Marshal(params) span.SetAttributes(attribute.String("appsignal.request.query_parameters", string(json))) ``` </CodeGroup> ### Request payload <Tip> This attribute's value needs to be serialized to a JSON string. It does not support a Hash or object from the integration language directly and will be silently ignored. </Tip> * Attribute name: `appsignal.request.payload` * Value type: JSON serialized object Report an incoming HTTP request's payload using this attribute. The values set in this span attribute can be filtered using the [`appsignal.config.filter_request_payload` config option](/opentelemetry/configuration/options#filter-request-payload). <CodeGroup> ```python Python theme={null} span.set_attribute("appsignal.request.payload", json.dumps({ "title": "My new blog post" "body": "Lorem ipsum" })) ``` ```go Go theme={null} import ( "encoding/json" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" ) payload := map[string]interface{}{ "param1": "value1", "param2": "value2", "nested": map[string]interface{}{ "param3": "value3", "param4": "value4", }, } json, _ := json.Marshal(payload) span.SetAttributes(attribute.String("appsignal.request.payload", string(json))) ``` </CodeGroup> ### Request session data <Tip> This attribute's value needs to be serialized to a JSON string. It does not support a Hash or object from the integration language directly and will be silently ignored. </Tip> * Attribute name: `appsignal.request.session_data` * Value type: JSON serialized object Report an incoming HTTP request's session data using this attribute. The values set in this span attribute can be filtered using the [`appsignal.config.filter_request_session_data` config option](/opentelemetry/configuration/options#filter-request-session-data). <CodeGroup> ```python Python theme={null} span.set_attribute("appsignal.request.session_data", json.dumps({ "user_id": 123 "theme": "dark" })) ``` ```go Go theme={null} import ( "encoding/json" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" ) session_data := map[string]interface{}{ "param1": "value1", "param2": "value2", "nested": map[string]interface{}{ "param3": "value3", "param4": "value4", }, } json, _ := json.Marshal(session_data) span.SetAttributes(attribute.String("appsignal.request.session_data", string(json))) ``` </CodeGroup> # OpenTelemetry Source: https://docs.appsignal.com/opentelemetry/installation Reporting application data to AppSignal through OpenTelemetry involves more installation steps than usual. Please ensure you follow all the steps carefully to set it up correctly. ## Install the AppSignal collector To report data to AppSignal, you need to install the AppSignal collector via one of the following installation methods: * [Hosted collector](/collector/hosted-vs-self-hosted): have AppSignal host the collector. * [Linux package](/collector/installation/linux-package): run the collector on the host you want to monitor. * [Docker image](/collector/installation/docker-image): run the collector in a Docker container to connect to other containers. * [Platform as a Service](/collector/installation/platform-as-a-service): run the collector in a Docker container, hosted by your hosting provider. If you have more than one application, or instances of an application, we recommend installing the collector to your infrastructure on its own instance, which all applications can report to. This will improve our reporting as we can piece together instrumentation data across different applications (distributed tracing). It is also more resource intensive to install the collector separately on each host. ## Configuring the AppSignal collector <Tip> You do not need to configure the collector when using AppSignal's hosted collector. </Tip> When configuring the collector, use the organization-level Push API key from the [API keys settings page](https://appsignal.com/redirect-to/organization?to=admin/api_keys). This will authenticate requests with AppSignal. Without a Push API key the collector will not start. <CodeGroup> ```toml title="Linux package" theme={null} # /etc/appsignal-collector.conf push_api_key = "0000-0000-0000-0000" ``` ```bash title="Docker run" theme={null} docker run \ --env APPSIGNAL_PUSH_API_KEY="0000-0000-0000-0000" \ --publish "8099:8099" \ appsignal/collector ``` ```yaml title="Docker Compose" theme={null} version: "3.8" services: appsignal-collector: image: appsignal/collector:latest environment: - APPSIGNAL_PUSH_API_KEY="0000-0000-0000-0000" ``` </CodeGroup> ## Install OpenTelemetry for your application To install the OpenTelemetry packages in your app, follow the instructions for the language your app uses: * [Ruby](/opentelemetry/installation/ruby) * [Elixir](/opentelemetry/installation/elixir) * [Node.js](/opentelemetry/installation/nodejs) * [Python](/opentelemetry/installation/python) * [Go](/go/installation) * [PHP](/php/installation) * [Java](/java/installation) * [Vercel](/vercel/traces#using-the-instrumentation-package) Make sure to follow the instructions, including installing any additional packages needed to have OpenTelemetry instrument the frameworks and libraries that your application uses. For other languages, you can follow the installation instructions in the [OpenTelemetry documentation](https://opentelemetry.io/docs/) for that language, alongside with our [language-agnostic generic installation instructions](/opentelemetry/installation/generic). You might also find it useful to use our installation instructions for the languages we support as reference. # OpenTelemetry Elixir Installation Source: https://docs.appsignal.com/opentelemetry/installation/elixir Make sure to [install the AppSignal collector](/opentelemetry/installation) before proceeding with these instructions. ## Install the OpenTelemetry packages Add the OpenTelemetry SDK and the OTLP exporter to your application's dependencies: <CodeGroup> ```elixir Elixir theme={null} def deps do [ # other dependencies... {:opentelemetry, "~> 1.3"}, {:opentelemetry_api, "~> 1.2"}, {:opentelemetry_exporter, "~> 1.6"}, ] end ``` </CodeGroup> Also add the OpenTelemetry instrumentation packages for the libraries and frameworks that your application uses. For example, if you're using Phoenix: <CodeGroup> ```elixir Elixir theme={null} def deps do [ # other dependencies... {:opentelemetry_phoenix, "~> 1.1"}, {:opentelemetry_cowboy, "~> 0.2"}, {:opentelemetry_ecto, "~> 1.2"} ] end ``` </CodeGroup> For other libraries and frameworks, you can [find OpenTelemetry instrumentation packages at the OpenTelemetry registry](https://opentelemetry.io/ecosystem/registry/?s=\&component=instrumentation\&language=elixir\&flag=all). ## Configure OpenTelemetry in your application Update the `config/config.exs` file in your application with the OpenTelemetry exporter and AppSignal configuration. Make sure to update the values below with your AppSignal application name, environment and push API key, and to replace the exporter endpoint with the address of your AppSignal collector if needed. <CodeGroup> ```elixir Elixir theme={null} # Replace these values with your AppSignal application name, environment # (autodetected from Mix) and push API key. These are used by the resource attributes # configuration below. name = "My app" push_api_key = "0000-0000-0000-0000" environment = if Kernel.function_exported?(Mix, :env, 0) do to_string(Mix.env()) else "development" end # Set the name of the service that is being monitored. A common choice is the # name of the framework used. This is used to group traces and metrics in AppSignal. service_name = "My service name" # Replace `http://localhost:8099` with the address of your AppSignal collector # if it's running on another host. endpoint = "http://localhost:8099" {:ok, hostname} = :inet.gethostname() {revision, _exitcode} = System.cmd("git", ["log", "--pretty=format:%h", "-n 1"]) config :opentelemetry, span_processor: :batch, traces_exporter: :otlp, resource: [ {"appsignal.config.name", name}, {"appsignal.config.environment", environment}, {"appsignal.config.push_api_key", push_api_key}, {"appsignal.config.revision", revision}, {"appsignal.config.language_integration", "elixir"}, {"appsignal.config.app_path", File.cwd!()}, {"host.name", hostname}, {"service.name", service_name} ] config :opentelemetry_exporter, otlp_protocol: :http_protobuf, otlp_endpoint: endpoint ``` </CodeGroup> ## Test the app! Now that all the components are connected, start your app and test if you see data arrive in AppSignal. Check the ["Errors > Issue list"](https://appsignal.com/redirect-to/app?to=exceptions) and ["Performance > Traces"](https://appsignal.com/redirect-to/app?to=performance/traces) page specifically. If after following our installation instructions you still don't see data in AppSignal, [let us know](mailto:support@appsignal.com?subject=OpenTelemetry%20issue) and we'll help you finalize your OpenTelemetry installation! # OpenTelemetry Generic Installation Source: https://docs.appsignal.com/opentelemetry/installation/generic Make sure to [install the AppSignal collector](/opentelemetry/installation) before proceeding with these instructions. ## Configure the OpenTelemetry SDK Follow the instructions in the [OpenTelemetry documentation](https://opentelemetry.io/docs/) to set up the SDK for your language. You must configure the OpenTelemetry SDK to export the data to the AppSignal collector. The AppSignal collector expects data to be sent using the OTLP protocol format over HTTP. It is often necessary to install an additional OpenTelemetry package to export in a specific format. The AppSignal collector does not currently support logging data, so it's recommended to disable the logging exporter to silence export errors. By default, the AppSignal collector listens on port `8099`. The OpenTelemetry exporters must be configured to send data to these endpoints on the collector: * Traces: `http://localhost:8099/v1/traces` * Metrics: `http://localhost:8099/v1/metrics` * Logs: `http://localhost:8099/v1/logs` Many OpenTelemetry exporter packages automatically set the export path to `/v1/traces` for traces, `/v1/metrics` for metrics and `/v1/logs` for logs, so you'd only need to specify `localhost:8099` as the endpoint. However, for some languages it may be necessary to specify the entire path. If you are running the AppSignal collector on a different host, replace `localhost` with the address of your AppSignal collector. ## Configure the OpenTelemetry resource The AppSignal collector requires certain attributes to be present in the OpenTelemetry resource. Configure the OpenTelemetry resource with the SDK with the following required attributes: * `appsignal.config.name`: The application's name in AppSignal. * `appsignal.config.environment`: The application's environment in AppSignal. * `appsignal.config.push_api_key`: The push API key to use to send data to AppSignal. This can be the same Push API key that was configured when installing the AppSignal collector. * `appsignal.config.revision`: Automatically create deploys in AppSignal by specifying the app revision. * `appsignal.config.language_integration`: Set the programming language name. This helps us recognize the programming language that is being used and improve how our servers interpret the data. Example values: "python", "rust", "ruby", "elixir", "go", "node.js". * `service.name`: The service name. See below for more details. * `host.name`: The name of the host. [See also our configuration options page](/opentelemetry/configuration/options) for a list of all supported config options. If you already have an application that uses the same name and environment, reported by one of our existing language integration packages, please use another name and/or environment. Data reported by AppSignal is shown in new UI elements and pages that are not compatible with the data reported by our integration packages. We recommend reporting the application OpenTelemetry data to a new AppSignal application so the UI will not be so confusing. ### Choosing a service name Choose a service name for your app that makes each component or service easily recognizable. This service name will be used to group namespaces by service. The resulting namespaces are formatted like so: `<service name>/<namespace>` If the service name is "My service name" and the namespace is "admin", the resulting namespace on AppSignal.com becomes: "My service namespace/admin" The important part of naming is that it makes sense to you and your team. A service name can be the name of the application, its purpose, or the name of the framework used. # OpenTelemetry Node.js Installation Source: https://docs.appsignal.com/opentelemetry/installation/nodejs Make sure to [install the AppSignal collector](/opentelemetry/installation) before proceeding with these instructions. ## Install the OpenTelemetry packages Use npm to add the OpenTelemetry SDK and the OTLP exporter to your application's dependencies: <CodeGroup> ```shell Shell theme={null} npm install @opentelemetry/sdk-node \ @opentelemetry/api \ @opentelemetry/sdk-trace-node \ @opentelemetry/sdk-metrics \ @opentelemetry/exporter-trace-otlp-proto \ @opentelemetry/exporter-metrics-otlp-proto \ @opentelemetry/auto-instrumentations-node \ @opentelemetry/semantic-conventions \ @opentelemetry/resources ``` </CodeGroup> The `@opentelemetry/auto-instrumentations-node` package will automatically instrument most applications and libraries. Check out [the package's README for a list of libraries and frameworks that it instruments](https://www.npmjs.com/package/@opentelemetry/auto-instrumentations-node). You can [find additional instrumentations for libraries and frameworks in the OpenTelemetry Registry](https://opentelemetry.io/ecosystem/registry/?s=\&component=instrumentation\&language=js\&flag=all). ## Configure OpenTelemetry in your application Add this `opentelemetry.cjs` file to your application with the OpenTelemetry exporter and AppSignal configuration. Make sure to update the values below with your AppSignal application name, environment and push API key, and to replace the exporter endpoint with the address of your AppSignal collector if needed. <CodeGroup> ```javascript JavaScript theme={null} const os = require("os"); const { NodeSDK } = require("@opentelemetry/sdk-node"); const { NodeTracerProvider } = require("@opentelemetry/sdk-trace-node"); const { PeriodicExportingMetricReader, AggregationTemporality, } = require("@opentelemetry/sdk-metrics"); const { resourceFromAttributes } = require("@opentelemetry/resources"); const { ATTR_SERVICE_NAME } = require("@opentelemetry/semantic-conventions"); const { OTLPTraceExporter, } = require("@opentelemetry/exporter-trace-otlp-proto"); const { OTLPMetricExporter, } = require("@opentelemetry/exporter-metrics-otlp-proto"); const { getNodeAutoInstrumentations, } = require("@opentelemetry/auto-instrumentations-node"); // Replace these values with your AppSignal application name, environment // and push API key. These are used by the resource attributes configuration below. const name = "My app"; const pushApiKey = "0000-0000-0000-0000"; const environment = process.env.NODE_ENV || "production"; // Set the name of the service that is being monitored. A common choice is the // name of the framework used. This is used to group traces and metrics in AppSignal. const serviceName = "My service name"; // Replace `http://localhost:8099` with the address of your AppSignal collector // if it's running on another host. const endpoint = "http://localhost:8099"; const revision = childProcess.execSync("git rev-parse --short HEAD").toString(); const resource = new resourceFromAttributes({ "appsignal.config.name": name, "appsignal.config.environment": environment, "appsignal.config.push_api_key": "0000-0000-0000-0000", "appsignal.config.revision": revision, "appsignal.config.language_integration": "node.js", "appsignal.config.app_path": process.cwd(), "host.name": os.hostname(), [ATTR_SERVICE_NAME]: "My service name", }); const sdk = new NodeSDK({ resource, traceExporter: new OTLPTraceExporter({ url: `${endpoint}/v1/traces`, }), metricReader: new PeriodicExportingMetricReader({ exportIntervalMillis: 10000, exporter: new OTLPMetricExporter({ url: `${endpoint}/v1/metrics`, }), }), instrumentations: [getNodeAutoInstrumentations()], }); sdk.start(); ``` </CodeGroup> ## Start your application with OpenTelemetry To run your application with OpenTelemetry, you need to use the `--require` flag to load the `opentelemetry.cjs` file before starting your application: <CodeGroup> ```bash Bash theme={null} node --require ./opentelemetry.cjs index.js ``` </CodeGroup> Update your `package.json` file to add `--require` to the command that starts your app. <CodeGroup> ```json JSON theme={null} { // other configuration... "scripts": { "server": "node --require ./opentelemetry.cjs index.js" } } ``` </CodeGroup> You can also use the `--require` flag with tools such as `ts-node` and `nodemon`. When using a wrapper CLI, such as `nest start` or `fastify start`, to start your application, use the `NODE_OPTIONS` environment variable to pass the flag to the Node.js runtime: <CodeGroup> ```sh Shell theme={null} NODE_OPTIONS='--require ./appsignal.cjs' nest start ``` </CodeGroup> ## Test the app! Now that all the components are connected, start your app with the required command line arguments and test if you see data arrive in AppSignal. Check the ["Errors > Issue list"](https://appsignal.com/redirect-to/app?to=exceptions) and ["Performance > Traces"](https://appsignal.com/redirect-to/app?to=performance/traces) page specifically. If after following our installation instructions you still don't see data in AppSignal, [let us know](mailto:support@appsignal.com?subject=OpenTelemetry%20issue) and we'll help you finalize your OpenTelemetry installation! # OpenTelemetry Python Installation Source: https://docs.appsignal.com/opentelemetry/installation/python To send OpenTelemetry data from your Python application to AppSignal, you can either use the [AppSignal for Python package](/python/installation) or install and configure OpenTelemetry manually. ## Using the AppSignal for Python package The AppSignal for Python package can automatically configure OpenTelemetry to send data to the AppSignal collector. It can also automatically enable OpenTelemetry instrumentations for popular libraries and frameworks. Follow the instructions in the [AppSignal for Python installation documentation](/python/installation) to install the package and set up the configuration file, then follow the instructions in the [AppSignal for Python collector configuration page](/python/configuration/collector) to use it with the AppSignal Collector. ## Installing OpenTelemetry manually Make sure to [install the AppSignal collector](/opentelemetry/installation) before proceeding with these instructions. ### Install the OpenTelemetry packages Add the OpenTelemetry SDK, OTLP exporter and instrumentation packages to your application's `requirements.txt`: <CodeGroup> ```txt Text theme={null} opentelemetry-api opentelemetry-sdk opentelemetry-exporter-otlp-proto-http ``` </CodeGroup> Also add the OpenTelemetry instrumentation packages for the libraries and frameworks that your application uses. For example, if you're using Django and Celery: <CodeGroup> ```txt Text theme={null} opentelemetry-instrumentation-celery opentelemetry-instrumentation-django ``` </CodeGroup> Check out [the OpenTelemetry registry for instrumentation packages](https://opentelemetry.io/ecosystem/registry/?s=\&component=instrumentation\&language=python\&flag=all) for most libraries and frameworks. ### Configure OpenTelemetry in your application Add this `appsignal.py` file to your application with the OpenTelemetry exporter and AppSignal configuration. Then, import that file before your application starts. Make sure to update the values below with your AppSignal application name, environment and push API key, and to replace the exporter endpoint with the address of your AppSignal collector if needed. <CodeGroup> ```python Python theme={null} import os import subprocess import socket from opentelemetry import trace, metrics from opentelemetry.sdk.resources import Resource from opentelemetry.sdk.trace import TracerProvider from opentelemetry.sdk.trace.export import BatchSpanProcessor from opentelemetry.sdk.metrics.export import ( AggregationTemporality, PeriodicExportingMetricReader, ) from opentelemetry.exporter.otlp.proto.http.trace_exporter import ( OTLPSpanExporter ) from opentelemetry.exporter.otlp.proto.http.metric_exporter import ( OTLPMetricExporter ) def initialize_opentelemetry(service_name): # Replace these values with your AppSignal application name, environment # and push API key. These are used by the resource attributes configuration below. name = "My app" push_api_key = "0000-0000-0000-0000" environment = "development" # Replace `http://localhost:8099` with the address of your AppSignal collector # if it's running on another host. endpoint = "http://localhost:8099" revision = subprocess.check_output( "git rev-parse --short HEAD", shell=True, text=True ).strip() resource = Resource(attributes={ "appsignal.config.name": name, "appsignal.config.environment": environment, "appsignal.config.push_api_key": push_api_key, "appsignal.config.revision": revision, "appsignal.config.language_integration": "python", "appsignal.config.app_path": os.getcwd() "host.name": socket.gethostname(), # Customize the service name "service.name": service_name, }) trace_provider = TracerProvider(resource=resource) span_processor = BatchSpanProcessor( OTLPSpanExporter(endpoint=f"{collector_host}/v1/traces") ) trace_provider.add_span_processor(span_processor) trace.set_tracer_provider(trace_provider) metric_exporter = OTLPMetricExporter( endpoint=f"{collector_host}/v1/metrics", ) metric_reader = PeriodicExportingMetricReader( metric_exporter, export_interval_millis=10000 ) metric_provider = MeterProvider( resource=resource, metric_readers=[metric_reader] ) metrics.set_meter_provider(metric_provider) ``` </CodeGroup> Then, in the same file, after the OpenTelemetry setup, initialize the OpenTelemetry instrumentations for the libraries and frameworks that your application uses. For example, if you're using the Django and Celery instrumentations: <CodeGroup> ```python Python theme={null} # Add this below the OpenTelemetry initialization from opentelemetry.instrumentation.django import DjangoInstrumentor from opentelemetry.instrumentation.celery import CeleryInstrumentor DjangoInstrumentor().instrument() CeleryInstrumentor().instrument() ``` </CodeGroup> Finally, call the `initialize_opentelemetry` function with the name of the service that is being monitored, as early as possible in your application's entry point. A common choice for the service name is the name of the framework used. #### Usage with Django In the `settings.py` file of your Django application, import the `appsignal.py` module at the beginning of the file and call the `initialize_opentelemetry` function: <CodeGroup> ```python Python theme={null} from .appsignal import initialize_opentelemetry # Set the name of the service that is being monitored. A common choice is the # name of the framework used. This is used to group traces and metrics in AppSignal. service_name = "Django" initialize_opentelemetry(service_name) ``` </CodeGroup> #### Usage with Celery In the `tasks.py` file of your Celery application, add a connection callback for worker processes and import the `appsignal.py` module within it. <CodeGroup> ```python Python theme={null} @worker_process_init.connect(weak=False) def init_celery_tracing(*args, **kwargs): from .appsignal import initialize_opentelemetry # Set the name of the service that is being monitored. A common choice is the # name of the framework used. This is used to group traces and metrics in AppSignal. service_name = "Celery" initialize_opentelemetry(service_name) ``` </CodeGroup> ### Test the app! Now that all the components are connected, start your app and test if you see data arrive in AppSignal. Check the ["Errors > Issue list"](https://appsignal.com/redirect-to/app?to=exceptions) and ["Performance > Traces"](https://appsignal.com/redirect-to/app?to=performance/traces) page specifically. If after following our installation instructions you still don't see data in AppSignal, [let us know](mailto:support@appsignal.com?subject=OpenTelemetry%20issue) and we'll help you finalize your OpenTelemetry installation! # OpenTelemetry Ruby Installation Source: https://docs.appsignal.com/opentelemetry/installation/ruby Make sure to [install the AppSignal collector](/opentelemetry/installation) before proceeding with these instructions. ## Install the OpenTelemetry gems Use Bundler to add the OpenTelemetry SDK, OTLP exporter and instrumentation packages to your application's Gemfile: <CodeGroup> ```sh Shell theme={null} bundle add opentelemetry-sdk opentelemetry-exporter-otlp opentelemetry-instrumentation-all ``` </CodeGroup> The `opentelemetry-instrumentation-all` package installs instrumentations for most frameworks and libraries. You can check out [a list of instrumented frameworks and libraries in the package's dependencies on RubyGems](https://rubygems.org/gems/opentelemetry-instrumentation-all/versions/0.74.0). You can also [find additional instrumentations for frameworks and libraries in the OpenTelemetry Registry](https://opentelemetry.io/ecosystem/registry/?s=\&component=instrumentation\&language=ruby\&flag=all). ## Configure OpenTelemetry in your application Add this `appsignal.rb` file to your application with the OpenTelemetry exporter and AppSignal configuration. Then, require this file in your application. For Rails applications, add it to an Rails initializer like `config/initializers/appsignal.rb`. Make sure to update the values below with your AppSignal application name, environment and push API key, and to replace the exporter endpoint with the address of your AppSignal collector if needed. <CodeGroup> ```ruby Ruby theme={null} require "socket" require "opentelemetry/sdk" require "opentelemetry/instrumentation/all" require "opentelemetry-exporter-otlp" # Replace these values with your AppSignal application name, environment # and push API key. These are used by the resource attributes configuration below. name = "My app" push_api_key = "0000-0000-0000-0000" environment = defined?(Rails) ? Rails.env.to_s : "development" # Set the name of the service that is being monitored. A common choice is the # name of the framework used. This is used to group traces and metrics in AppSignal. service_name = "My service name" # Replace `http://localhost:8099` with the address of your AppSignal collector # if it's running on another host. endpoint = "http://localhost:8099/v1/traces" revision = `git rev-parse --short HEAD`.strip OpenTelemetry::SDK.configure do |c| c.resource = OpenTelemetry::SDK::Resources::Resource.create( "appsignal.config.name" => name, "appsignal.config.environment" => environment, "appsignal.config.push_api_key" => push_api_key, "appsignal.config.revision" => revision, "appsignal.config.language_integration" => "ruby", "appsignal.config.app_path" => Dir.pwd, "host.name" => Socket.gethostname, ) c.service_name = service_name c.add_span_processor( OpenTelemetry::SDK::Trace::Export::BatchSpanProcessor.new( OpenTelemetry::Exporter::OTLP::Exporter.new( :endpoint => endpoint, :compression => "none" ) ) ) c.use_all end ``` </CodeGroup> ## Test the app! Now that all the components are connected, start your app and test if you see data arrive in AppSignal. Check the ["Errors > Issue list"](https://appsignal.com/redirect-to/app?to=exceptions) and ["Performance > Traces"](https://appsignal.com/redirect-to/app?to=performance/traces) page specifically. If after following our installation instructions you still don't see data in AppSignal, [let us know](mailto:support@appsignal.com?subject=OpenTelemetry%20issue) and we'll help you finalize your OpenTelemetry installation! # OpenTelemetry Troubleshooting Source: https://docs.appsignal.com/opentelemetry/troubleshooting When no data is reported from your app to AppSignal, please check the common problems below. ## No data is being reported ### The OpenTelemetry export endpoint is misconfigured OpenTelemetry apps default to exporting data to `http://localhost:4318`. AppSignal requires a custom endpoint to send data to the AppSignal collector. The AppSignal collector can run as a hosted or self-hosted type. Read our [Hosted vs Self-hosted page](/collector/hosted-vs-self-hosted) for more information about the difference between these collector types. Follow the help for the collector type your application uses below: * [Hosted collector](#hosted-collector) * [Self-hosted collector](#self-hosted-collector), installed as a [Linux package] and [Docker image] #### Hosted collector When using the hosted collector, make sure to use the collector's URL shown in the [add app wizard](https://appsignal.com/redirect-to/organization?to=sites/new) as the OpenTelemetry exporter's endpoint. In the add app wizard select the language your application uses that AppSignal supports for OpenTelemetry, or use the "More languages" option, to view the hosted collector endpoint. It may be in a code example, assigned to a variable named `endpoint`. The hosted collector's format is as follows: * `https://COLLECTOR-ID.REGION.appsignal-collector.net` The exporter endpoint needs to be configured either via the `OTEL_EXPORTER_OTLP_ENDPOINT` environment variable or in the app itself, where OpenTelemetry is configured. Refer to the [language-specific installation guide][install guide] your application is using for more detail. #### Self-hosted collector When using a self-hosted collector, the OpenTelemetry exporter endpoint needs to point to the location the collector is running. If the collector is running on the same host (installed using the [Linux package]) the hostname is `localhost`. If the collector runs in a [Docker container][Docker image] or Kubernetes cluster, the hostname may differ based on the specified service name. We recommend naming the service `appsignal` and updating the exporter's endpoint to match the `appsignal` hostname. * Hostname, several values are possible: * [Linux package]: `localhost:8099` * [Docker image]: `appsignal:8099` * Examples: * `http://localhost:8099`, or `http://appsignal:8099` on Docker. For some languages, in the OpenTelemetry SDK the URI scheme (`http`/`https`) should not be set as part of the OpenTelemetry exporter endpoint. Please refer to the [installation guide](/opentelemetry/installation) for the language your application uses. The exporter endpoint needs to be configured either via the `OTEL_EXPORTER_OTLP_ENDPOINT` environment variable or in the app itself, where OpenTelemetry is configured. Refer to the [language-specific installation guide][install guide] your application is using for more detail. #### Exporter endpoints Some OpenTelemetry exporters may need to be configured per OpenTelemetry data type to specific endpoints. When configuring a trace/span exporter, use the trace endpoint, for metrics, use the metrics endpoint, etc. These endpoints on the AppSignal collector are: * Trace data: * `/v1/traces` or, * `/v1/traces` * Metric data: * `/v1/metrics` or, * `/v1/metrics` * Log data: * `/v1/logs` or, * `/v1/logs` ### The OpenTelemetry export protocol is not set to http/protobuf The AppSignal collector only supports the OpenTelemetry Protocol (OTLP) over HTTP with Protobuf encoding. Required config: * Protocol format: `http/protobuf` If OpenTelemetry in your app is using gRPC or JSON as an export format, update the configuration to use the HTTP/protobuf format. To configure the exporter protocol format, follow [the installation steps](/opentelemetry/installation) for the language your application is using. ### The self-hosted collector is not running or is unreachable To send data to AppSignal, the self-hosted collector needs to have started correctly. Export errors visible in the application logs may indicate the collector isn't running. To check if it's running, check the collector logs. The collector logs can be found in: * The container logs for the [Docker container installation method](/collector/installation/docker-image). Check your container manager for the best way to access container logs. * The system logs for the [Linux package installation method](/collector/installation/linux-package#debugging). If the collector is running but can't be reached, check internal network settings to see if the application is able to reach the collector's host. ## Missing or incomplete data reported If you're only seeing some data and are missing more data about what your application is doing, it's likely due to missing OpenTelemetry instrumentation in your application. OpenTelemetry does not automatically instrument everything out of the box. To collect data from specific frameworks and libraries, you'll need to install and configure additional instrumentation libraries. To report more data, install the appropriate OpenTelemetry instrumentation libraries for the corresponding libraries used in your application. Refer to [add additional OpenTelemetry instrumentation guide](/guides/instrumentation/additional-opentelemetry-instrumentation) for your application's language on how to install more instrumentation packages. [install guide]: /opentelemetry/installation.html [Linux package]: /collector/installation/linux-package.html [Docker image]: /collector/installation/docker-image.html # Organizations Source: https://docs.appsignal.com/organization Let's say you have your own startup but still do some freelance work for clients on the side. You'll want to have your own AppSignal billing setup for your startup, while still being part of the AppSignal organizations of your clients. This is easily done with "organizations" in AppSignal. Organizations are basically umbrellas for your applications, which we charge on the organization level. ## Creating a new organization Once you sign up for an AppSignal account you will need to create an Organization, except when you accept an invitation to another organization. If you already have an account you can [create a new organization][profile-organizations] from your user account settings. Because you'll probably work with new people and apps in this organization, you'll start a new 30 day trial period for this new organization. ## Renaming an organization In case you want to rename your organization contact us at [support@appsignal.com](mailto:support@appsignal.com), or through the in-app chat. Please ensure you're an owner of the organization otherwise we will have to decline your request. Please provide the following details in your message: 1. Tell us which organization you want to rename and what to rename it to. 2. If the organization's slug in the URL needs to be updated as well (`appsignal.com/your-organization-slug`), let us know what it needs to be changed to as well. **Note**: If the organization's URL slug has to be updated as well, the change will break all existing links in emails and other notifications. We will not put a redirect in place to link from the old organization slug to the new one. New notifications will use the updated organization slug. ## Leaving an organization In your user profile you can find a [list of all the organizations][profile-organizations] you have access to. If you're not the only owner of an organization you can leave it. Once you do that you will not have access to the organization anymore, the only way to undo this is asking the owner to invite you again. [profile-organizations]: https://appsignal.com/users/accounts # Data exports Source: https://docs.appsignal.com/organization/data-exports AppSignal allows you to generate exports of your apps exception and performance data quickly and conveniently, enabling you to analyze exception and performance data with your preferred third-party tools. ## This documentation explains how to: * [Export charts in AppSignal](#how-to-export-charts) * [Export performance and exception data in AppSignal](#how-to-export-data) * [Manage and download CSV data exports in AppSignal](#how-to-manage-exported-data) ## Exportable data You can export the following data in the following formats: | Data Type | Page/Feature | Export Formats | | ----------- | ---------------------------- | -------------- | | Exceptions | Exception Incidents | CSV | | | Exception Incident Samples | CSV | | Performance | Performance Incidents | CSV | | | Performance Incident Samples | CSV | | | Performance Actions | CSV | | Charts | Chart Data | PNG, JSON, CSV | Note: All CSV exports are provided in gzipped format. ## How to export charts 1. Click the "Share" button on the chart you'd like to export. 2. Configure the export's graph title desired format. 3. Click download, and save the generated export. <img alt="Export a graph" /> ## How to export data Data can be exported by clicking on the Export dropdown in the filter bar and selecting "Export all records." <img alt="Create an export" /> Currently, it is not possible to export a filtered dataset. This will generate an export which, once processed, can be downloaded from the exports overview. ## How to manage exported data You can view your exports on your organization's Exports page. Here, all exports will be shown with their requested export date and time, application, environment, status, export type, requestor, and row count. Export status update automatically, there is no need to refresh the page if you're waiting for a processing export to complete. <img alt="View exports" /> # Notifier management Source: https://docs.appsignal.com/organization/notifier-management Notifiers notify you when your application encounters an incident, such as an error, performance issue, or anomaly. Admins can manage notifiers to streamline application set-up, for example, by setting up a default notifier and managing notifiers for all an organization's applications. This is particularly useful for organizations with many apps, like agencies. ### This documentation covers: * [Notifiers available in AppSignal](#available-notifiers) * [How to view all notifiers in AppSignal](#view-all-notifiers) * [How to manage notifiers in AppSignal](#manage-notifiers) ## Available notifiers AppSignal currently supports the following notifiers: * [Discord](/application/integrations/discord) * [Google Hangouts Chat](#google-hangouts-chat) * [Microsoft Teams](/application/integrations/teams) * [OpsGenie](/application/integrations/opsgenie) * [PagerDuty](/application/integrations/pagerduty) * [Slack](/application/integrations/slack) * [Webhook](/application/integrations/webhooks) Webhooks can be used to configure AppSignal to work with additional services. Many third-party notifiers offer their own documentation for connecting to AppSignal via our Webhook. For more details, you can read their documentation: * [All Quiet](https://docs.allquiet.app/integrations/inbound/appsignal) * [ilert](https://docs.ilert.com/inbound-integrations/appsignal) * [Squadcast](https://support.squadcast.com/integrations/alert-source-integrations-native/appsignal) * [Zenduty](https://www.zenduty.com/docs/appsignal-integration/) You can see a complete list of supported third-party integrations in our [integrations documentation](https://docs.appsignal.com/application/integrations.html). ## View all notifiers To manage notifiers you will need to have admin permissions for your organization. Admins can navigate to Organization settings > Notifications > Notifications. In the Notifications overview, you can manage and delete notifiers. <img alt="Screenshot of notifier scope" /> ## Manage notifiers To manage a notifier, click 'Manage'. Here you can: * [Manage notifier settings](#manage-notifier-settings) * [Manage notifier scope](#manage-notifier-scope) * [Make notifier default on new applications](#make-notifier-default-on-new-applications) * [Manage notifier events](#manage-notifier-events) ### Manage notifier settings In the Settings for this notifier section, you can manage the name, and for email notifiers, the reminder interval of your notifier. The reminder interval instructs AppSignal how often to send a notification when there is an open alert. <img alt="Screenshot of notifier settings" /> ### Manage notifier scope In notifier scope, you can manage the scope of a notifier across all of your organization's applications. Scope can be defined per application and per environment, so for example, for all apps running in the production environment. <img alt="Screenshot of notifier default" /> ### Make notifier default on new applications When enabled, this notifier will be set up by default on all new applications. If you have a Slack notifier for all production apps and make it default, all new applications you monitor with AppSignal will automatically have that notifier configured. <img alt="Screenshot of notifier events" /> ### Manage notifier events Here you can manage what application events trigger your notifier, such as deploys, errors, performance issues, and triggers, scoped per namespace. So, for example, only sending notifications for error events in the `API` namespace. <img alt="Screenshot of notifier scope" /> # Organization team members Source: https://docs.appsignal.com/organization/team/members If you're the owner of an account you can invite other people to become members of your organization so they can access apps in your organization on AppSignal. You can invite a new member in the invitations screen in your organization's settings. You can find your organization settings by clicking the settings link at the top right of the screen. You can make the invitee an account owner by the checking the owner box. If you check one of the teams the invitee will become a member of those teams. See [Manage owners & teams](/organization/team/owners) for more information about owners and teams. <img alt="Invite a new user" /> Once you invite a new member the invitation will show up in the outstanding invitations table. <img alt="Outstanding invitations" /> If the invitee has not received an invitation email you can resend the email. Please contact us at [support@appsignal.com](mailto:support@appsignal.com) if invitation emails aren't making it to an inbox. You can delete the invitation if you have second thoughts about inviting a person. Once the invitation has been accepted the invitation will not be shown in the outstanding invitations table anymore. The person will now be present in the members screen, you can remove the member here if needed. <img alt="Members" /> # Organization owners Source: https://docs.appsignal.com/organization/team/owners There are two ways to manage permissions in AppSignal. A user can be an owner or a member of [one or more teams](/organization/team/teams). An owner has access to everything in your organization. Owners can invite other users and can determine which other users get to be owner. You can see the owners in the members screen. You can add change the role of users to member, owner or remove the user. <img alt="Members" /> # Organization teams Source: https://docs.appsignal.com/organization/team/teams If you want to give certain people in your organization access to a limited set of your apps you can use teams. Every user in your organization is a member of the "Everyone" team. You cannot remove anybody from the Everyone team. Besides the Everyone team you can create as many teams with specific members as you like. You can specify which apps a team has access to. <img alt="Teams" /> Once you create a team you can edit its name, app and members. Select a member and add him/her to the team, or remove a member from the team. <img alt="Edit team member" /> Select an app and give the team access to this app, or remove access to the app. <img alt="Edit team apps" /> # Two-Factor Authentication Enforcement Source: https://docs.appsignal.com/organization/two-factor-authentication-enforcement Two-Factor Authentication Enforcement allows you to require all members of an organization to enable Two-Factor Authentication on their AppSignal account. ## Enable Two-Factor Authentication Enforcement Two-Factor Authentication Enforcement can be enabled in your [organization's Members settings](https://appsignal.com/redirect-to/organization?to=admin/members) screen: <img alt="Screenshot of organization members screen with 2FA Enforcement option" /> When activated organization members without Two-Factor Authentication will be given a [grace period](#grace-periods) to enable it. An email notification and warning bar in the AppSignal app will inform them that Two-Factor Authentication has been enforced: <img alt="Screenshot of organization members screen with 2FA Enforcement option" /> Clicking on the link in the email, or banner will take the user to the Two-Factor Authentication set-up screen. ## Grace periods When Two-Factor Authentication Enforcement in enabled organisation members are given a grace period to set-up Two-Factor Authentication on their AppSignal accounts: | Member | Grace period | | ---------------- | ------------ | | New members | 3 days | | Existing members | 7 days | If a user does not enable Two-Factor Authentication before the end of their grace period they will locked out of the organization until it's enabled: <img alt="Screenshot of organization members screen with 2FA Enforcement option" /> ## Disable Two-Factor Authentication Enforcement Two-Factor Authentication Enforcement can be disabled in your [organization's Members settings](https://appsignal.com/redirect-to/organization?to=admin/members) screen: <img alt="Screenshot of organization members screen with 2FA Enforcement option" /> When disabled members will no longer require Two-Factor Authentication to access the organization. # Performance / tracing Source: https://docs.appsignal.com/performance-tracing In AppSignal, performance and tracing describe the same core flow from two sides. A trace shows what happened during a request, job, or script run. Performance views help you understand where that trace spent time and where it slowed down. When a trace is slow, you can use AppSignal to inspect the spans and events inside it. When a trace ends with an exception, that same trace becomes the context you use to debug the error. ## Follow the trace Use these guides when you want to investigate performance in more detail: * [Find slow requests](/guides/slow-requests) * [Find slow queries](/guides/slow-queries) * [Errors](/errors) ## Add more instrumentation When the default instrumentation is not enough, add more detail to your traces with: * [Add additional OpenTelemetry Instrumentation](/guides/instrumentation/additional-opentelemetry-instrumentation) * [Custom instrumentation](/custom-instrumentation) # AppSignal for PHP Source: https://docs.appsignal.com/php You can instrument your PHP application using the [AppSignal for PHP package](https://packagist.org/packages/appsignal/appsignal-php). It supports any [PHP](https://php.net) application and provides auto-instrumentation for [Laravel](https://laravel.com) and [Symfony](https://symfony.com) frameworks. The package allows you to send trace, metric, and log data from your PHP application to AppSignal. <Snippet /> ## Setting up AppSignal for PHP Follow the installation instructions in the next steps to set up AppSignal in your PHP application and start reporting data. # AppSignal for PHP: Command-line tools Source: https://docs.appsignal.com/php/command-line The AppSignal for PHP package ships with a CLI tool. This tool provides commands that make it easier to install AppSignal in a PHP application and diagnose configuration problems. ```bash Shell theme={null} vendor/bin/appsignal ``` ## Install A CLI command to install AppSignal in your PHP application. Read more about the [`appsignal install`](/php/command-line/install) CLI command. ## Demo A CLI command that sends example data to AppSignal. When the command runs, it sends a trace, an error, and a log from your machine to AppSignal. Read more about the [`appsignal demo`](/php/command-line/demo) CLI command. ## Verify A verification command that you can use to check the configuration of your AppSignal integration. Read more about the [`appsignal verify`](/php/command-line/verify) CLI command. # AppSignal for PHP: Demo command Source: https://docs.appsignal.com/php/command-line/demo <VersionRequirements /> The AppSignal for PHP package includes a command-line tool that sends example data to AppSignal. When the command runs, it sends trace, error, and log samples from your PHP environment to AppSignal. This command-line tool is useful for testing AppSignal on a system and validating your local configuration. The same test is also run during installation when using the [AppSignal installer](/php/command-line/install). ## Usage To run the demonstration command, run the following terminal command from your project's root folder: ```bash Shell theme={null} vendor/bin/appsignal demo ``` ## Available options | Option | Usage | Description | | -------------- | ---------------------------------- | -------------------------------------------------------------------------- | | `application` | `--application=<application name>` | Set the name of the reported application. (Optional) | | `environment` | `--environment=<environment_name>` | Set the environment to use in the command, e.g. `production` or `staging`. | | `push-api-key` | `--push-api-key=<Push API key>` | Set the Push API key used to authenticate the application. | # AppSignal CLI: Install Source: https://docs.appsignal.com/php/command-line/install Command-line tool to install AppSignal in a PHP application. Documentation for usage, options and configuration methods. <VersionRequirements /> The install command sets up AppSignal in your PHP application. The command goes through six steps: 1. Detects your application framework (Laravel, Symfony, or plain PHP), 2. Installs auto-instrumentation packages, 3. Scaffolds config file in `config/appsignal.php` if it doesn't exist, 4. Collects required config values interactively, pre-filling any that were found in your environment, 5. Sends example data (trace, exception, and log) to AppSignal to verify configuration, 6. Updates `.env` file with missing configuration values. ## Usage Run the following terminal command from your project's root folder: ```bash Shell theme={null} vendor/bin/appsignal install ``` ## Command options The `install` command options allow you to pass required configuration values or skip the demo. | Option | Description | | ---------------------- | --------------------------------------------------------------- | | `--push-api-key` | AppSignal Push API key | | `--collector-endpoint` | AppSignal collector endpoint URL | | `--app-name` | Your application name | | `--app-environment` | Your application environment (e.g. `production`, `development`) | | `--skip-demo` | Skip sending demo data (also skips `.env` updates) | Unless `--skip-demo` option is passed, the `install` command runs [the `demo` command](/php/command-line/demo) automatically. If all configuration values are passed in through command options, the interactive prompts are skipped entirely. To learn more about configuration options, visit [AppSignal for PHP Configuration documentation](/php/configuration/options). # AppSignal for PHP CLI: Verify command Source: https://docs.appsignal.com/php/command-line/verify <VersionRequirements /> The AppSignal for PHP CLI includes a command-line tool that verifies AppSignal configuration. When the command runs, it loads configuration [from multiple sources in a three-step-process](/php/configuration/load-order) and checks that all required configuration options are provided. If the command fails, it outputs a list of configuration keys with problems. ## Usage To run the `verify` command, run the following terminal command from your project's root folder: ```bash Shell theme={null} vendor/bin/appsignal verify ``` # AppSignal for PHP configuration Source: https://docs.appsignal.com/php/configuration Configure AppSignal for PHP through the `config/appsignal.php` file. The `appsignal install` command creates this file for you. ```sh Shell theme={null} vendor/bin/appsignal install ``` ## Configure AppSignal Open `config/appsignal.php` and set the required values: <CodeGroup> ```php title="Laravel" theme={null} return [ 'active' => true, 'app_name' => 'My app', 'environment' => 'production', 'push_api_key' => env('APPSIGNAL_PUSH_API_KEY'), 'collector_endpoint' => env('APPSIGNAL_COLLECTOR_ENDPOINT'), ]; ``` ```php title="Symfony" theme={null} return [ 'active' => true, 'app_name' => 'My app', 'environment' => 'production', 'push_api_key' => $_ENV['APPSIGNAL_PUSH_API_KEY'], 'collector_endpoint' => $_ENV['APPSIGNAL_COLLECTOR_ENDPOINT'], ]; ``` ```php title="Vanilla PHP" theme={null} return [ 'active' => true, 'app_name' => 'My app', 'environment' => 'production', 'push_api_key' => $_ENV['APPSIGNAL_PUSH_API_KEY'], 'collector_endpoint' => $_ENV['APPSIGNAL_COLLECTOR_ENDPOINT'], ]; ``` </CodeGroup> Set the Push API key and collector endpoint URL in your `.env` file: ```bash title=".env" theme={null} APPSIGNAL_PUSH_API_KEY=<your-push-api-key> APPSIGNAL_COLLECTOR_ENDPOINT=<your-collector-endpoint-url> ``` AppSignal provides the Push API key and collector endpoint URL when you create a new application. ## Validate configuration The AppSignal for PHP package includes an `appsignal validate` command to check that the current configuration is valid. ```sh Shell theme={null} vendor/bin/appsignal validate > The AppSignal config is valid. ``` ## Test the app Once your application is configured, start it and check whether data arrives in AppSignal. The ["Performance > Traces"](https://appsignal.com/redirect-to/app?to=performance/traces) page is a good place to start, where you'll see samples of traces from your application. If you still don't see data after following the installation instructions, [contact support](mailto:support@appsignal.com?subject=PHP%20installation%20issue) and we'll help you finish setup. All available AppSignal configuration options are listed on the [configuration options page](/php/configuration/options). # AppSignal for PHP config load order Source: https://docs.appsignal.com/php/configuration/load-order You can configure AppSignal for PHP through the `config/appsignal.php` config file, or with environment variables. The configuration is loaded in a three-step process, starting with the package defaults and ending with reading the config file. The configuration options can be mixed without losing configuration from a different option. ## Load order * 1. [Package defaults - `default`](#1-package-defaults) * 2. [Environment variables - `env`](#2-environment-variables) * 3. [Config file - `file`](#3-config-file) ## 1. Package defaults The package starts with loading its default configuration, setting paths and enabling certain features. The package defaults can be found in the [configuration options documentation](/php/configuration/options). ## 2. Environment variables AppSignal looks for configuration in environment variables. When found, these override the package defaults. You can pass environment variables to one-off PHP scripts: ```bash Shell theme={null} export APPSIGNAL_APP_NAME="my custom app name" ``` or for your PHP application this is typically done via a `.env` file: ```bash title=".env" theme={null} APPSIGNAL_ACTIVE=true APPSIGNAL_APP_NAME="my custom app name" APPSIGNAL_PUSH_API_KEY=local ``` Supported environment variables are documented in the `env_key` definition for each [configuration option](/php/configuration/options). ## 3. Config file AppSignal looks for configuration in the `config/appsignal.php` file. Options in this file override all configuration options set in previous steps. ```php title="config/appsignal.php" theme={null} return [ 'app_name' => 'my custom app name', // ... other options ]; ``` Supported keys are documented in the `config_key` definition for each [configuration option](/php/configuration/options). # AppSignal for PHP configuration options Source: https://docs.appsignal.com/php/configuration/options AppSignal for PHP can be configured through the `config/appsignal.php` file or by using environment variables. This page lists all available configuration options. Learn more about the [configuration load order](/php/configuration/load-order). Once you have configured AppSignal, you can validate the current config: ```sh Shell theme={null} vendor/bin/appsignal validate ``` ## Available options * Required options * [`collector_endpoint`](#option-collector_endpoint) * [`environment`](#option-environment) * [`name`](#option-name) * [`push_api_key`](#option-push_api_key) * Options * [`active`](#option-active) * [`app_path`](#option-app_path) * [`filter_attributes`](#option-filter_attributes) * [`filter_function_parameters`](#option-filter_function_parameters) * [`filter_request_payload`](#option-filter_request_payload) * [`filter_request_query_parameters`](#option-filter_request_query_parameters) * [`filter_request_session_data`](#option-filter_request_session_data) * [`hostname`](#option-hostname) * [`ignore_actions`](#option-ignore_actions) * [`ignore_errors`](#option-ignore_errors) * [`ignore_logs`](#option-ignore_logs) * [`ignore_namespaces`](#option-ignore_namespaces) * [`request_headers`](#option-request_headers) * [`response_headers`](#option-response_headers) * [`revision`](#option-revision) * [`send_function_parameters`](#option-send_function_parameters) * [`send_request_payload`](#option-send_request_payload) * [`send_request_query_parameters`](#option-send_request_query_parameters) * [`send_request_session_data`](#option-send_request_session_data) * [`service_name`](#option-service_name) ## collector\_endpoint <a /> | Field | Value | | ---------------------- | ------------------------------ | | Config file key | `collector_endpoint` | | System environment key | `APPSIGNAL_COLLECTOR_ENDPOINT` | | Required | yes | | Type | `String` | | Default value | `null` (unset by default) | ### Description The URL of the AppSignal collector to send trace, metric, and log data to. AppSignal shows this URL when you create a new application, and it's also available for existing applications. ```php title="config/appsignal.php" theme={null} return [ 'collector_endpoint' => $_ENV['APPSIGNAL_COLLECTOR_ENDPOINT'] ?? null, // ... other options ]; ``` ## environment <a /> | Field | Value | | ---------------------- | ------------------------- | | Config file key | `environment` | | System environment key | `APPSIGNAL_APP_ENV` | | Required | yes | | Type | `String` | | Default value | `null` (unset by default) | ### Description The environment of the app to be reported to AppSignal. ```php title="config/appsignal.php" theme={null} return [ 'environment' => $_ENV['APPSIGNAL_APP_ENV'] ?? 'production', // ... other options ]; ``` <Note> **Note**: Changing the [name](#option-name) or environment of an existing app will create a new app on AppSignal.com. </Note> ## name <a /> | Field | Value | | ---------------------- | ------------------------- | | Config file key | `name` | | System environment key | `APPSIGNAL_APP_NAME` | | Required | yes | | Type | `String` | | Default value | `null` (unset by default) | ### Description The display name of your application on AppSignal.com. ```php title="config/appsignal.php" theme={null} return [ 'name' => 'My App', // ... other options ]; ``` <Note> **Note**: Changing the name or [environment](#option-env) of an existing app will create a new app on AppSignal.com. </Note> ## push\_api\_key <a /> | Field | Value | | ---------------------- | ------------------------- | | Config file key | `push_api_key` | | System environment key | `APPSIGNAL_PUSH_API_KEY` | | Required | yes | | Type | `String` | | Default value | `null` (unset by default) | ### Description The organization-level key used to authenticate with the Push API. Read more about the [AppSignal Push API key](/appsignal/terminology#push-api-key). ```php title="config/appsignal.php" theme={null} return [ 'push_api_key' => $_ENV['APPSIGNAL_PUSH_API_KEY'] ?? '00000000-0000-0000-0000-000000000000', // ... other options ]; ``` ## active <a /> | Field | Value | | ---------------------- | -------------------------- | | Config file key | `active` | | System environment key | `APPSIGNAL_ACTIVE` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `false` | ### Description Configure whether AppSignal is active for a given environment. Most commonly used in the [file configuration](/php/configuration) per environment. ## app\_path <a /> | Field | Value | | --------------- | -------------------------- | | Config file key | `app_path` | | Required | no | | Type | `String` | | Default value | detected from project root | ### Description The location of the app on the host's file system. Helps AppSignal clean up backtraces by stripping the absolute app path from backtrace lines, showing only paths within the project directory. This makes our [Backtrace links](/application/backtrace-links) feature possible. The AppSignal package sets this value automatically based on the detected project root. If the automatic app path detection doesn't work, you can override it: ```php title="config/appsignal.php" theme={null} return [ 'app_path' => '/var/www/html/your-app' // ... other options ]; ``` ## filter\_attributes <a /> | Field | Value | | ---------------------- | ----------------------------- | | Config file key | `filter_attributes` | | System environment key | `APPSIGNAL_FILTER_ATTRIBUTES` | | Required | no | | Type | `Array<String>` | | Default value | `[]` | ### Description The `filter_attributes` config option allows you to filter out specific attributes from being reported to AppSignal. This can be useful to filter out sensitive or non-relevant information from being reported. If an attribute is filtered out this way, it will not show up in the interface at all. ```php title="config/appsignal.php" theme={null} return [ 'filter_attributes' => ['my.secret.attribute', 'some.opentelemetry.attribute'], // ... other options ]; ``` ## filter\_function\_parameters <a /> | Field | Value | | ---------------------- | -------------------------------------- | | Config file key | `filter_function_parameters` | | System environment key | `APPSIGNAL_FILTER_FUNCTION_PARAMETERS` | | Required | no | | Type | `Array<String>` | | Default value | `[]` | ### Description This config option allows you to filter out any function parameters set in the [`appsignal.function.parameters` span attribute](/guides/custom-data/function-parameters). AppSignal replaces values for the keys listed in the `filter_function_parameters` config option with `[FILTERED]`. ```php title="config/appsignal.php" theme={null} return [ 'filter_function_parameters' => ['api_token', 'secret'], // ... other options ]; ``` ## filter\_request\_payload <a /> | Field | Value | | ---------------------- | ---------------------------------- | | Config file key | `filter_request_payload` | | System environment key | `APPSIGNAL_FILTER_REQUEST_PAYLOAD` | | Required | no | | Type | `Array<String>` | | Default value | `[]` | ### Description This config option allows you to filter out any request payload data set in the [`appsignal.request.payload` span attribute](/guides/custom-data/request-parameters). AppSignal replaces values for the keys listed in the `filter_request_payload` config option with `[FILTERED]`. Read more about [request query parameter filtering](/application/parameter-filtering). ```php title="config/appsignal.php" theme={null} return [ 'filter_request_payload' => ['password', 'cvv'], // ... other options ]; ``` ## filter\_request\_query\_parameters <a /> | Field | Value | | ---------------------- | ------------------------------------------- | | Config file key | `filter_request_query_parameters` | | System environment key | `APPSIGNAL_FILTER_REQUEST_QUERY_PARAMETERS` | | Required | no | | Type | `Array<String>` | | Default value | `[]` | ### Description This config option allows you to filter out any request query parameters set in the [`appsignal.request.query_parameters` span attribute](/guides/custom-data/request-parameters). AppSignal replaces values for the keys listed in the `filter_request_query_parameters` config option with `[FILTERED]`. Read more about [request query parameter filtering](/application/parameter-filtering). ```php title="config/appsignal.php" theme={null} return [ 'filter_request_query_parameters' => ['password', 'cvv'], // ... other options ]; ``` ## filter\_request\_session\_data <a /> | Field | Value | | ---------------------- | --------------------------------------- | | Config file key | `filter_request_session_data` | | System environment key | `APPSIGNAL_FILTER_REQUEST_SESSION_DATA` | | Required | no | | Type | `Array<String>` | | Default value | `[]` | ### Description The `filter_request_session_data` config option allows you to filter out any request session data set in the [`appsignal.request.session_data` span attribute](/guides/custom-data/request-session-data). AppSignal replaces values for the keys listed in the `filter_request_session_data` config option with `[FILTERED]`. Read more about [request session data filtering](/application/session-data-filtering). ```php title="config/appsignal.php" theme={null} return [ 'filter_request_session_data' => ['password', 'cvv'], // ... other options ]; ``` ## hostname <a /> | Field | Value | | ---------------------- | -------------------- | | Config file key | `hostname` | | System environment key | `APPSIGNAL_HOSTNAME` | | Required | no | | Type | `String` | | Default value | detected from system | ### Description Helps AppSignal recognize different hosts for traces and tag them automatically with the hostname. The AppSignal package sets this value automatically using `gethostname()`. ## ignore\_actions <a /> | Field | Value | | ---------------------- | -------------------------- | | Config file key | `ignore_actions` | | System environment key | `APPSIGNAL_IGNORE_ACTIONS` | | Required | no | | Type | `Array<String>` | | Default value | `[]` | ### Description With this config option you can specify a list of actions that will be ignored by AppSignal. Everything that happens including exceptions will not be transmitted to AppSignal. This can be useful to ignore health check endpoints or other actions that you don't want to monitor. Read more about [ignoring actions](/guides/filter-data/ignore-actions). ```php title="config/appsignal.php" theme={null} return [ 'ignore_actions' => ['GET /health_check', 'POST /ping'], // ... other options ]; ``` ## ignore\_errors <a /> | Field | Value | | ---------------------- | ------------------------- | | Config file key | `ignore_errors` | | System environment key | `APPSIGNAL_IGNORE_ERRORS` | | Required | no | | Type | `Array<String>` | | Default value | `[]` | ### Description This config option allows you to ignore specific errors from being reported to AppSignal. This can be useful to ignore expected errors or errors that can't be solved. Read more about [ignoring errors](/guides/filter-data/ignore-errors). ```php title="config/appsignal.php" theme={null} return [ 'ignore_errors' => ['MyCustomError', 'ExpectedError'], // ... other options ]; ``` ## ignore\_logs <a /> | Field | Value | | ---------------------- | ----------------------- | | Config file key | `ignore_logs` | | System environment key | `APPSIGNAL_IGNORE_LOGS` | | Required | no | | Type | `Array<String>` | | Default value | `[]` | ### Description List of log messages that will be ignored. Any log message containing any of the elements of the list will not be transmitted to AppSignal. A small subset of regex syntax is supported, read more about it in our [Ignore Logs](/guides/filter-data/ignore-logs) guide. The expected format is a comma-separated list of values. ```php title="config/appsignal.php" theme={null} return [ 'ignore_logs' => ["^success", "OK"], // ... other options ]; ``` ## ignore\_namespaces <a /> | Field | Value | | ---------------------- | ----------------------------- | | Config file key | `ignore_namespaces` | | System environment key | `APPSIGNAL_IGNORE_NAMESPACES` | | Required | no | | Type | `Array<String>` | | Default value | `[]` | ### Description This config option allows you to ignore specific namespaces from being reported to AppSignal. This can be useful to ignore specific parts of your application from being monitored. Read more about [namespaces](/application/namespaces). ```php title="config/appsignal.php" theme={null} return [ 'ignore_namespaces' => ['admin', 'secret'], // ... other options ]; ``` ## request\_headers <a /> | Field | Value | | ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | | Config file key | `request_headers` | | System environment key | `APPSIGNAL_REQUEST_HEADERS` | | Required | no | | Type | `Array<String>` | | Default value | `["accept", "accept-charset", "accept-encoding", "accept-language", "cache-control", "connection", "content-length", "host", "range"]` | ### Description Configure which request headers to include when a request is made to an HTTP server. This option is an allowlist. It only includes the headers that are configured. If the list is empty, no headers are included. AppSignal reads request headers from the HTTP request. Each key is a normalized (lowercase) header name. ```php title="config/appsignal.php" theme={null} return [ 'request_headers' => ['accept-encoding', 'content-length', 'user-agent'], // ... other options ]; ``` To configure AppSignal to not store any HTTP request headers, explicitly set the config value to an empty array. ```php title="config/appsignal.php" theme={null} return [ 'request_headers' => [], // ... other options ]; ``` ## response\_headers <a /> | Field | Value | | ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | | Config file key | `response_headers` | | System environment key | `APPSIGNAL_RESPONSE_HEADERS` | | Required | no | | Type | `Array<String>` | | Default value | `["accept", "accept-charset", "accept-encoding", "accept-language", "cache-control", "connection", "content-length", "date", "range"]` | ### Description Configure which response headers to include when a request is made by an HTTP client. This option is an allowlist. It only includes the headers that are configured. If the array is empty, no headers are included. Each item in this array should be a normalized HTTP response header name (lowercase). ```php title="config/appsignal.php" theme={null} return [ 'response_headers' => ['accept', 'accept-charset', 'accept-encoding'], // ... other options ]; ``` To configure AppSignal to not store any HTTP response headers, explicitly set the config value to an empty array. ```php title="config/appsignal.php" theme={null} return [ 'response_headers' => [], // ... other options ]; ``` ## revision <a /> | Field | Value | | ---------------------- | -------------------- | | Config file key | `revision` | | System environment key | `APPSIGNAL_REVISION` | | Required | no | | Type | `String` | | Default value | detected from git | ### Description The currently running version of your app. AppSignal will create a deploy marker when this value changes, and tag all incoming data with the current revision. The AppSignal package sets this value automatically using `git rev-parse HEAD`. Read more about deploy markers in the [deploy markers topic](/application/markers/deploy-markers). ## send\_function\_parameters <a /> | Field | Value | | ---------------------- | ------------------------------------ | | Config file key | `send_function_parameters` | | System environment key | `APPSIGNAL_SEND_FUNCTION_PARAMETERS` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `true` | ### Description Configure whether to include function parameters in traces. If set to `false` no such data is sent to our servers. These values are set with the [`appsignal.function.parameters` span attribute](/guides/custom-data/function-parameters). ```php title="config/appsignal.php" theme={null} return [ 'send_function_parameters' => false, // ... other options ]; ``` ## send\_request\_payload <a /> | Field | Value | | ---------------------- | -------------------------------- | | Config file key | `send_request_payload` | | System environment key | `APPSIGNAL_SEND_REQUEST_PAYLOAD` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `true` | ### Description Configure whether to send request payload data in traces. If set to `false` no such data is sent to our servers. These values are set with the [`appsignal.request.payload` span attribute](/guides/custom-data/request-parameters). For more information please read about [request payload filtering](/application/parameter-filtering). ```php title="config/appsignal.php" theme={null} return [ 'send_request_payload' => false, // ... other options ]; ``` ## send\_request\_query\_parameters <a /> | Field | Value | | ---------------------- | ----------------------------------------- | | Config file key | `send_request_query_parameters` | | System environment key | `APPSIGNAL_SEND_REQUEST_QUERY_PARAMETERS` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `true` | ### Description Configure whether to include request query parameters in traces. If set to `false` no such data is sent to our servers. These values are set with the [`appsignal.request.query_parameters` span attribute](/guides/custom-data/request-parameters). For more information please read about [request parameter filtering](/application/parameter-filtering). ```php title="config/appsignal.php" theme={null} return [ 'send_request_query_parameters' => false, // ... other options ]; ``` ## send\_request\_session\_data <a /> | Field | Value | | ---------------------- | ------------------------------------- | | Config file key | `send_request_session_data` | | System environment key | `APPSIGNAL_SEND_REQUEST_SESSION_DATA` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `true` | ### Description Configure whether to send request session data in traces. If set to `false` no such data is sent to our servers. These values are set with the [`appsignal.request.session_data` span attribute](/guides/custom-data/request-session-data). For more information please read about [request session data filtering](/application/session-data-filtering). ```php title="config/appsignal.php" theme={null} return [ 'send_request_session_data' => false, // ... other options ]; ``` ## service\_name <a /> | Field | Value | | ---------------------- | ------------------------- | | Config file key | `service_name` | | System environment key | `APPSIGNAL_SERVICE_NAME` | | Required | no | | Type | `String` | | Default value | `null` (unset by default) | ### Description The service name helps AppSignal recognize different services and automatically groups their traces into a matching namespace. Choose a name that fits your application, like "Web server", "Background worker", "Email service", "Authentication service", etc. ```php title="config/appsignal.php" theme={null} return [ 'service_name' => 'My service name', // ... other options ]; ``` # PHP exception handling Source: https://docs.appsignal.com/php/exception-handling Most applications raise some errors that aren't bugs in your code. They happen when the app encounters unexpected input, like a bot filling in a form. To stop these errors from showing up as problems in AppSignal, you can handle them in code or let AppSignal ignore certain errors entirely. ## Ignore errors AppSignal configuration lets you [ignore errors](/guides/filter-data/ignore-errors). Provide a list of error names in a denylist, and AppSignal will not track them when they are raised. ## `Appsignal::setError` To record a handled exception use the `Appsignal::setError()` helper method. This is useful when catching and handling an error gracefully but still wanting to track it in AppSignal. For example, to monitor how often a fallback path is triggered. ```php PHP theme={null} try { SomeClass::riskyOperation(); } catch (Throwable $e) { Appsignal::setError($e); throw $e; } ``` <Note> The errors passed as an argument to `Appsignal::setError()` must implement the base `Throwable` interface. </Note> # AppSignal for PHP installation Source: https://docs.appsignal.com/php/installation ### Install AppSignal for PHP package Install AppSignal for PHP: ```bash Shell theme={null} composer require appsignal/appsignal-php ``` ### Initialize AppSignal Run the `install` command to scaffold the configuration file, install framework auto-instrumentation, and send example data to AppSignal: ```bash Shell theme={null} vendor/bin/appsignal install --push-api-key=<push-api-key> --collector-endpoint=<collector-endpoint> --app-name=<app-name> --app-environment=<your-environment> ``` The `appsignal install` command detects your application environment, installs auto-instrumentation packages, scaffolds `config/appsignal.php` in your project root, sends example data to AppSignal, and updates the `.env` file if necessary. [Learn more about the `install` command](/php/command-line/install). # PHP custom instrumentation Source: https://docs.appsignal.com/php/instrumentation The AppSignal for PHP package provides out-of-the-box instrumentations for your PHP application. However, sometimes you need fine-grained observability, which requires manual instrumentation. For these cases, use the `Appsignal::instrument` method and customize the data sent to AppSignal using the helper methods. <Warning> Data sent to AppSignal must not contain any personal data, such as names or email addresses. Sanitize your application's data before sending it to AppSignal. If you need to identify a person, use alternatives like a user ID, hash, or pseudonym. </Warning> ## Creating spans The `Appsignal` class provides a helper for creating spans. ### `instrument` Creates and activates a new span. Pass a closure to have the span closed automatically, or omit it to manage the span lifecycle manually. #### With a closure If you use a closure, AppSignal closes the active span automatically. ```php PHP theme={null} Appsignal::instrument( name: 'process-order', attributes: ['order_id' => $orderId], closure: function () { // do work here Appsignal::setAttributes(['order_status' => 'processed']); }, ); ``` #### Without a closure Without a closure, the `instrument` method returns an instance of the `ActiveSpan` class, a thin wrapper around the OpenTelemetry span and its scope. Close this span manually by calling `$span->end()`. ```php PHP theme={null} $activeSpan = Appsignal::instrument( name: 'upload-file', attributes: ['file_name' => $filename], ); try { uploadFile($file); } catch (Throwable $e) { Appsignal::setError($e); } finally { $activeSpan->end(); } ``` ## Helpers The base `Appsignal` class provides helper methods to add custom data to traces or spans. The following sections describe each helper. <Note> The code examples below assume your code is already being instrumented (for example, inside a Laravel or Symfony route handler). If your code is not already instrumented, you must create a root span by calling `Appsignal::instrument()` and use the helpers inside of it. </Note> ### `addAttributes` Add attributes to the current span. ```php PHP theme={null} Appsignal::addAttributes([ 'user_id' => $user->id, 'user_plan' => $user->plan, ]); ``` ### `addHeaders` Adds request headers to the current span. If the header name already exists, the value is overwritten. Request headers are shown for sampled traces in AppSignal. See [the Request header customization guide](/guides/custom-data/request-headers) for more information. ```php PHP theme={null} Appsignal::addHeaders(['custom-header' => 'some-value']); ``` ### `addTags` Add tags to the current span. Tags appear as filterable metadata in AppSignal and are prefixed with `appsignal.tag.` internally. ```php PHP theme={null} Appsignal::addTags([ 'locale' => 'en', 'version' => '2.1.0', ]); ``` See the [tagging guide](/guides/tagging) for more information on how tags work in AppSignal. ### `setAction` Sets the action name on the current span. AppSignal displays this as the transaction name and uses it to group samples. ```php PHP theme={null} Appsignal::setAction('OrdersController::create'); ``` ### `setNamespace` Sets the namespace of the root span. ```php PHP theme={null} Appsignal::setNamespace('admin'); ``` ### `setParams` Set the query parameters of the incoming request. The `$params` must be a value that [can be serialized as JSON](https://www.php.net/manual/en/function.json-encode.php). ```php PHP theme={null} $params = [ 'param1' => 'value1', 'param2' => 'value2', 'nested' => [ 'param3' => 'value3', 'param4' => 'value4', ], ]; Appsignal::setParams($params); ``` ### `setPayload` Set the payload of the incoming request. The `$payload` must be a value that [can be serialized as JSON](https://www.php.net/manual/en/function.json-encode.php). ```php PHP theme={null} $payload = [ 'key1' => 'value1', 'key2' => 'value2', 'nested' => [ 'key3' => 'value3', 'key4' => 'value4', ], ]; Appsignal::setPayload($payload); ``` ## `ActiveSpan` `Appsignal::instrument()` returns an `ActiveSpan` instance that proxies all standard OpenTelemetry API `SpanInterface` [methods](https://open-telemetry.github.io/opentelemetry-php/classes/OpenTelemetry-API-Trace-SpanInterface.html). If you need low-level control over the span, use these methods to attach data or events to it directly. ```php PHP theme={null} $activeSpan = Appsignal::instrument('render-report'); $activeSpan->setAttribute('report.type', 'pdf'); $activeSpan->addEvent('rendering-started'); someExpensiveMethod(); $activeSpan->end(); ``` # PHP integrations Source: https://docs.appsignal.com/php/integrations <Note> Learn more about why [adding additional instrumentation](/guides/instrumentation/additional-opentelemetry-instrumentation) to your application is recommended. </Note> This page lists some of the PHP integrations that AppSignal supports. AppSignal for PHP is compatible with any OpenTelemetry based auto-instrumentation package. The full list of available auto-instrumentation packages for PHP can be found on [Packagist](https://packagist.org/search/?query=open-telemetry\&tags=instrumentation), along with their installation instructions. <Note> Is your app not reporting the data you'd like to see? Don't hesitate to [contact us](mailto:support@appsignal.com) and let us know which libraries you're using. We'll try to help get more useful data reported. </Note> ## PHP framework instrumentations The following PHP frameworks are auto-instrumented by default. * [Laravel](/php/integrations/laravel) * [Symfony](/php/integrations/symfony) # Laravel Source: https://docs.appsignal.com/php/integrations/laravel [Laravel](https://laravel.com) is a batteries-included framework for PHP that enables the development of web applications. The AppSignal for PHP provides auto-instrumentation for Laravel applications and will send trace, error, and log records automatically. No additional steps are required to get started. The `vendor/bin/appsignal install` command creates a config file in `config/appsignal.php`, which you can use to configure AppSignal. To learn more about AppSignal configuration options, visit the [configuration documentation](/php/configuration/options). # Monolog Source: https://docs.appsignal.com/php/integrations/monolog [Monolog](https://github.com/Seldaek/monolog) is the most popular logging library for PHP. You can use Monolog directly to send logs to AppSignal. Install the Monolog auto-instrumentation package: ```bash Shell theme={null} composer require open-telemetry/opentelemetry-logger-monolog ``` Then add `Appsignal\Integrations\Monolog\Handler` to Monolog's handler stack. ```php PHP theme={null} use Appsignal\Integrations\Monolog\Handler; use Monolog\Logger; $logger = new Logger('app'); $logger->pushHandler(Handler::withLevel('info')); $logger->info('My log message'); ``` Visit [logging documentation](/logging/integrations/php) to find out more about AppSignal logging capabilities. # Symfony Source: https://docs.appsignal.com/php/integrations/symfony [Symfony](https://symfony.com) is a high-performance PHP framework for web development. The tracing and metrics features of AppSignal will work out of the box with the Symfony framework. ## Logging You can configure your logger to send logs to Appsignal. ### Monolog If you are using `Monolog`, you can add an AppSignal handler to the [Monolog handler stack](https://symfony.com/doc/current/logging.html#handlers-writing-logs-to-different-locations) that will send logs to AppSignal. ```yml title="config/packages/monolog.yaml" theme={null} monolog: handlers: # other handlers appsignal: type: service id: appsignal.monolog.handler channels: ["app", "event"] # configure which channels to send to AppSignal ``` After that, add a service definition for `'appsignal.monolog.handler'` that uses the `Appsignal\Integrations\Monolog\Handler` class. ```yml title="config/services.yaml" theme={null} services: # ... other services appsignal.monolog.handler: class: Appsignal\Integrations\Monolog\Handler factory: ['Appsignal\Integrations\Monolog\Handler', "withLevel"] arguments: ["info"] # configure log level that will reach AppSignal ``` ### Stand-alone logger You can also use the stand-alone logger and send logs to AppSignal using the `Appsignal::log` helper method. This method requires no configuration and will send logs only to AppSignal. ```php PHP theme={null} use Appsignal\Appsignal; use Appsignal\Severity; Appsignal::log( message: 'A test log', severity: Severity::INFO, attributes: ['region' => 'eu'], loggerName: 'my-custom-logger', ); ``` # AppSignal for PHP requirements Source: https://docs.appsignal.com/php/requirements There are two requirements to get started with the PHP package: 1. An actively supported [PHP version](https://www.php.net/supported-versions). See our [maintenance policy](/support/maintenance-policy). 2. The OpenTelemetry PHP extension. We will guide you through installing the OpenTelemetry extension. ## Install OpenTelemetry PHP extension The OpenTelemetry PHP extension provides hooks in PHP functions that this package uses to instrument your application. This is a PHP extension that you need to install and enable in your PHP environment. First, make sure the required build dependencies are available on your system. <CodeGroup> ```bash title="Ubuntu / Debian" theme={null} sudo apt-get install gcc make autoconf ``` ```shell title="macOS" theme={null} brew install gcc make autoconf ``` </CodeGroup> Then, install the OpenTelemetry PHP extension using either [PECL](https://pecl.php.net/), [pie](https://github.com/php/pie), [pickle](https://github.com/FriendsOfPHP/pickle), or [docker-php-extension-installer](https://github.com/mlocati/docker-php-extension-installer): <CodeGroup> ```shell title="PECL" theme={null} pecl install opentelemetry ``` ```shell title="pie" theme={null} # Install pie (skip this step if pie is already installed) curl -L https://github.com/php/pie/releases/latest/download/pie.phar -o /usr/local/bin/pie && chmod +x /usr/local/bin/pie # Install the extension pie install open-telemetry/ext-opentelemetry ``` ```shell title="pickle" theme={null} # Install pickle (skip this step if pickle is already installed) curl -L https://github.com/FriendsOfPHP/pickle/releases/latest/download/pickle.phar -o /usr/local/bin/pickle && chmod +x /usr/local/bin/pickle # Install the extension pickle install opentelemetry ``` ```dockerfile title="docker-php-extension-installer" theme={null} # Use the docker-php-extension-installer script in your Dockerfile when using official PHP Docker images ADD --chmod=0755 https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/ RUN install-php-extensions opentelemetry ``` </CodeGroup> Finally, enable the extension in your PHP installation's configuration file. The configuration file is usually named `php.ini`, and its location can be found by running `php --ini`. Add the following lines to it: ```ini INI theme={null} [opentelemetry] extension=opentelemetry.so ``` <Note> When using the [docker-php-extension-installer](https://github.com/mlocati/docker-php-extension-installer) script to install the `opentelemetry` extension, the extension is automatically enabled and you don't need to manually edit the `php.ini` file. </Note> ## Create a new AppSignal application Please follow the [installation guide](/guides/new-application) first, when adding a new application to AppSignal. At the end of that guide, you will receive a Push API key and a collector endpoint URL. You will need both to configure AppSignal for PHP. # AppSignal for Python Source: https://docs.appsignal.com/python AppSignal supports [Python] applications through [OpenTelemetry](#opentelemetry). Once installed, the AppSignal package will send your application's error and performance data to AppSignal. ## OpenTelemetry OpenTelemetry is an open-source initiative that streamlines and standardizes telemetry data collection. OpenTelemetry supports multiple languages, including Python, and consists of multiple components: tracing, metrics, and logs. We support OpenTelemetry's tracing component in our Python integration for better error reporting and performance measurements. [Learn more about OpenTelemetry via the project's official website.][OpenTelemetry] ## Installation The [Python installation documentation](/python/installation) will guide you through the steps needed to install AppSignal. ## Configuration Our [Configuration documentation](/python/configuration) will guide you through the steps needed to configure AppSignal. ## Custom Instrumentation Our [Custom instrumentation](/python/instrumentation/instrumentation) documentation will walk you through all the steps needed to create custom instrumentation with AppSignal. ## Supported Libraries We currently offer support for the following Python libraries: * [Celery](/python/instrumentations/celery) * [Django](/python/instrumentations/django) * [FastAPI](/python/instrumentations/fastapi) * [Flask](/python/instrumentations/flask) * [Jinja2](/python/instrumentations/jinja2) * [MySQL](/python/instrumentations/mysql) * [Pika](/python/instrumentations/pika) * [PostgreSQL](/python/instrumentations/postgresql) * [Redis](/python/instrumentations/redis) * [Requests](/python/instrumentations/requests) * [Starlette](/python/instrumentations/starlette) * [SQLAlchemy](/python/instrumentations/sqlalchemy) * [SQLite](/python/instrumentations/sqlite) * [WSGI/ASGI](/python/instrumentations/wsgi) [Python]: https://www.python.org/ [OpenTelemetry]: https://opentelemetry.io/ # AppSignal for Python: Command-line tools Source: https://docs.appsignal.com/python/command-line The AppSignal Python package ships with several command-line tools. These tools make it easier to install AppSignal in an application, send deploy notifications and diagnose any problems with the installation. ## Install A command-line tool to install AppSignal in your Python application. Read more about the [appsignal install][cli-install] command-line tool. ## Diagnose A self-diagnostic tool that can be used to debug the installation and configuration of your AppSignal integration. It is one of the first tools that our support team requests you to run when debugging an issue. Read more about the [appsignal diagnose][cli-diagnose] command-line tool. ## Demo A command-line tool that sends demonstration samples to AppSignal. When the tool is run, it sends an error and performance sample from your machine to AppSignal. Read more about the [appsignal demo][cli-demo] command-line tool. [cli-install]: /python/command-line/install.html [cli-diagnose]: /python/command-line/diagnose.html [cli-demo]: /python/command-line/demo.html # AppSignal for Python: Demo tool Source: https://docs.appsignal.com/python/command-line/demo <VersionRequirements /> The AppSignal for Python package includes a command-line tool that sends demonstration samples to AppSignal. When the tool is run, it sends an error and performance sample from your machine to AppSignal. This command-line tool is useful for testing AppSignal on a system and validating your local configuration. The same test is also run during installation when using the [AppSignal installer](/python/command-line/install). To learn more about how to use the demonstration command, visit the [Debugging page][debugging]. ## Usage To run the demonstration tool, run the following terminal command from your project's root folder: <CodeGroup> ```bash Bash theme={null} python -m appsignal demo ``` </CodeGroup> ## Available Options | Option | Usage | Description | | -------------- | ---------------------------------- | -------------------------------------------------------------------------- | | `application` | `--application=<application name>` | Set the name of the reported application. (Optional) | | `environment` | `--environment=<environment_name>` | Set the environment to use in the command, e.g. `production` or `staging`. | | `push-api-key` | `--push-api-key=<Push API key>` | Set the Push API key used to authenticate the application. | [debugging]: /support/debugging.html # AppSignal for Python: Diagnose tool Source: https://docs.appsignal.com/python/command-line/diagnose <VersionRequirements /> The AppSignal for Python package includes a self-diagnostic tool that can be used to debug the installation and configuration of your AppSignal integration. It is one of the first tools that our support team requests you to run when debugging an issue. ## The diagnostic report You can use this diagnostic tool to test and validate your AppSignal installation. It outputs useful information to debug issues and it checks if AppSignal agent is able to run on the machine's architecture and communicate with the AppSignal servers. This diagnostic tool collects and outputs the following: * Information about the AppSignal package. * Information about the host system and Python. * If the AppSignal [agent](/appsignal/how-appsignal-operates#agent) can run on the host system. * All configured configuration options (including default values). * If the configuration is valid and active. * If the Push API key is present and valid (internet connection required). * Where configuration option values originate from. * If the required system paths exist, are writable, and which user and group are owners. * Small parts of the tail from the available log files. You can read more about how to use the diagnose command in our [Debugging](/support/debugging) documentation. ## Submitting the report After the report has been created, you will be prompted to send the report to our servers. If this prompt is accepted, the report will be send to our servers and you will receive a support token. When you [send this support token to us](mailto:support@appsignal.com) we will review the report and help you debug the issue. We've seen that copy-pasting the report output usually loses formatting and makes it harder to read, which is why it's send to our servers in the JSON format. After sending the report to our servers, a link to the web view of the report is printed in the diagnose output. This web view will also show any validation problems and warnings our system detected. ## Usage On the command-line in your project run: <CodeGroup> ```bash Bash theme={null} python -m appsignal diagnose ``` </CodeGroup> If you're experiencing an issue in production and need to send the report to AppSignal for support, you can run the following command to generate and send the report to our servers: <CodeGroup> ```bash Bash theme={null} python -m appsignal diagnose --send-report ``` </CodeGroup> ## Options | Option | Usage | Description | | ------------------ | ----------------------------------------------- | ---------------------------------------------- | | `[no]-send-report` | [`--[no-]send-report`](#report-submission-flag) | Automatically send, or do not send the report. | ### Report submission flag Using the `--send-report` flag it's possible to automatically send the report without being prompted. This makes it easier to use in non-interactive environments. To run diagnose and submit the report data to AppSignal, run the below command: <CodeGroup> ```bash Bash theme={null} python -m appsignal diagnose --send-report ``` </CodeGroup> To run diagnose without sending the report data to AppSignal, run the below command: <CodeGroup> ```bash Bash theme={null} python -m appsignal diagnose --no-send-report ``` </CodeGroup> ## Configuration output format ### Configuration option values format The configuration options are printed to the CLI as their inspected values. This means we print them as Python would in a console. * Strings values are printed with double quotes around them, e.g. `"My app name"`. * Booleans values are printed as their raw values: `True` and `False`. * Arrays values are printed as a collection of values surrounded by square brackets, e.g. `["accept", "accept-charset"]`. * Empty Arrays are printed as two square brackets: `[]`. ### Configuration sources The configuration section also displays the origin of config option values, which can help identify sources that override values defined in other config sources. You can read more about configuration sources their load order, and priority in the [configuration load order](/python/configuration/load-order) documentation. The configuration options are displayed based on the source of their values and the number of sources that set them, like in the below example: ```text Shell theme={null} Configuration # Option with a value loaded only from the default source send_params: True # Option with one source # A different source than the default source name: "My app name" (Loaded from file) # Option with multiple sources # Listed in order of priority (highest priority last) active: True Sources: default: False file: False env: True ``` [debugging]: /support/debugging.html # AppSignal for Python: Install Source: https://docs.appsignal.com/python/command-line/install Command-line tool to install AppSignal in a Python application. Documentation on usage, options and configuration methods. <VersionRequirements /> The documentation tells you everything you need to know about installing AppSignal via the command-line tool. ## Description The command-line tool helps with setting up the configuration for your application. Integration with Python applications may require additional steps, because the AppSignal installer does not know how your application is set up. We recommend you our [installation guide](/guides/new-application) when adding a new application to AppSignal and follow the steps per framework in our [integrations documentation](/python/instrumentations/). Once the installation is complete, the [demo tool command](/python/command-line/demo) is run automatically to verify that the installation was successful. The demo tool command sends sample data from your application to the AppSignal servers, which helps you verify that everything is working properly. ## Configuration methods There are two configuration methods provided by the command-line installer: 1. [Configuration via a configuration file](#1-configuration-file) 2. [Configuration via environment variables](#2-environment-variables). ### 1. Configuration file AppSignal can be configured via a configuration file called `__appsignal__.py`, located in the root directory of your application. When chosing this option our installer will write your configuration to this file. When configuring your AppSignal integration via the configuration file, the Push API key you provide to the installer will be written into the `__appsignal__.py` configuration file. We do not recommend adding this key to version control systems such as Git, SVN or Mercurial. Instead, use the `APPSIGNAL_PUSH_API_KEY` environment variable to store your API key. You can read more about configuring your application in our [configuration documentation](/python/configuration). ### 2. Environment variables AppSignal can be configured through system environment variables. If you select this option, no [configuration file](#1-configuration-file) will be generated. You can read more about configuring your application in our [configuration documentation](/python/configuration). ## Usage To install appsignal via the command-line, navigate to your project directory and run the following command: <CodeGroup> ```bash Bash theme={null} python -m appsignal install --push-api-key <Push API key> # For example python -m appsignal install --push-api-key 1234-1234-1234-1234 ``` </CodeGroup> Your application's "Push API key" will be displayed in the [installation wizard](https://appsignal.com/redirect-to/organization?to=sites/new) and is also available in the administration section of your organization's settings, or via [this link](https://appsignal.com/redirect-to/organization?to=admin/api_keys). ## Available Options | Option | Usage | Description | | -------------- | ---------------------------------- | ---------------------------------------------------------- | | `push-api-key` | `--push-api-key=<Push API key>` | Set the Push API key used to authenticate the application. | | `application` | `--application=<application name>` | Set the name of the reported application. | # AppSignal Python Configuration Source: https://docs.appsignal.com/python/configuration This documentation explains how to configure AppSignal. For more information on installing AppSignal, follow the steps in our [installation documentation](/python/installation/). ### Application Environment By default, the AppSignal for Python integration will report the current application in the "development" environment. You can use the `environment` configuration option to set a different environment. For example, in your `__appsignal__.py` file: <CodeGroup> ```python Python theme={null} # __appsignal__.py appsignal = Appsignal( # ... environment="production" ) ``` </CodeGroup> You can also use the `APPSIGNAL_APP_ENV` environment variable. ### Reporting Deploys You can use [Deploy Markers](/application/markers/deploy-markers) to report new deploys of your Python application. You can combine Deploy Markers with [Backtrace Links](/application/backtrace-links) to directly link from AppSignal to the source code on platforms like GitHub and GitLab. Deploy markers can be configured using the `revision` config option or the `APP_REVISION` environment variable. We recommend using Git commit SHAs or a tag in your SCM. For example, for Git applications, add the following code to the `__appsignal__.py` file: <CodeGroup> ```python Python theme={null} # __appsignal__.py import subprocess revision = None try: revision = subprocess.check_output( "git rev-parse --short HEAD", shell=True, text=True ).strip() except subprocess.CalledProcessError: pass appsignal = Appsignal( # ... revision=revision ) ``` </CodeGroup> ## Importing the Configuration File The AppSignal for Python integration needs to be loaded and started in your application. To load and start the integration, import the `appsignal` module and call the `appsignal.start()` method on app start or in the `main` method. <Tip> AppSignal also supports popular web frameworks directly, such as [Django](/python/instrumentations/django), [Flask](/python/instrumentations/flask), [FastAPI](/python/instrumentations/fastapi) or [Starlette](/python/instrumentations/starlette). If you're using a web framework we support directly, follow the instructions for that framework instead of the generic instructions on this page. </Tip> <CodeGroup> ```python Python theme={null} # Your app file # Add this import statement import appsignal def main(): # Add this method call appsignal.start() if __name__ == '__main__': main() ``` </CodeGroup> ## Add Instrumentation Packages The next step is to instrument Python libraries such as Django, Celery, etc. Instrumenting libraries will provide a broader set of monitoring data, allowing you to understand your application's performance better. You can read more about installing and configuring instrumentations in our [Python instrumentations documentation][instrumentations]. [Python language]: https://www.python.org/ [OpenTelemetry]: https://opentelemetry.io/ [instrumentations]: /python/instrumentations [django]: /python/instrumentations/django.html # AppSignal Python Collector Configuration Source: https://docs.appsignal.com/python/configuration/collector This documentation explains how to configure AppSignal for Python to use the [AppSignal Collector](/collector) to send data to AppSignal. This documentation assumes that you have already followed [the installation instructions](/python/installation). **This is an experimental feature.** The following functionality **will not be available** when using the AppSignal collector: * [NGINX metrics](/metrics/nginx) * [Host metrics](/metrics/host-metrics) * [StatsD metrics](/standalone-agent/statsd) The following functionality **is only available** when using the AppSignal collector: * [Logging](/logging/integrations/python) ## Deploying a collector You can deploy your own collector by following the instructions in the [AppSignal Collector documentation](/collector/installation). You can also have AppSignal host a collector for you using the ["Hosted Collector"](https://appsignal.com/redirect-to/organization?to=admin/hosted_collectors) page in your organization's settings. ## Configuring the collector endpoint Set [the `collector_endpoint` configuration option](/python/configuration/options#option-collector_endpoint) to the address of your collector. When using a hosted collector, this address can be found under "Collector URL" in the "Hosted Collector" settings page. <CodeGroup> ```python title="__appsignal__.py" theme={null} from appsignal import Appsignal appsignal = Appsignal( # ... other settings ... collector_endpoint="https://collector.example", ) ``` ```sh title="Environment variables" theme={null} APPSIGNAL_COLLECTOR_ENDPOINT="https://collector.example" ``` </CodeGroup> The AppSignal for Python integration will now send data to the configured collector instead of using the bundled agent. # AppSignal for Python load order Source: https://docs.appsignal.com/python/configuration/load-order This documentation outlines how the AppSignal configuration is loaded in your Python application. There are two different methods for [configuring your AppSignal integration](/python/configuration), which can be used simultaneously: * Config file (`__appsignal__.py`) * Environment variables A list of available options can be found in the [Configuration options](/python/configuration/options) documentation. ## Load order The configuration is loaded in a four-step process: 1. [Package defaults - `default`](#1-package-defaults) 2. [System detected settings - `system`](#2-system-detected-settings) 3. [Environment variables - `env`](#3-environment-variables) 4. [Initial configuration - `initial`](#4-initial-configuration-given-to-appsignal) ## 1. Package defaults First, the default configuration is loaded, which sets paths and enables certain features. This source will be listed under `default` in your application's config and is visible in the [Diagnose report](https://docs.appsignal.com/support/debugging.html). ## 2. System detected settings The package detects what kind of system it's running on and configures itself accordingly. For example, if running inside a container-based system such as Docker or Heroku, the configuration option `running_in_container` is set to `true`. This source will be listed under `system` in your application's config and is visible in the [Diagnose report](https://docs.appsignal.com/support/debugging.html). ## 3. Environment variables AppSignal will look for Configuration options set via Environment variables. The Environment variable value will override values for the same Configuration options defined in previous steps. <CodeGroup> ```bash Bash theme={null} export APPSIGNAL_APP_NAME="my custom app name" # start your app here ``` </CodeGroup> This source will be listed under `env` in your application's configuration, and is visible in the [Diagnose report](https://docs.appsignal.com/support/debugging.html). ## 4. Initial configuration given to `Appsignal` Finally, the initial configuration is loaded via the `Appsignal` function called from the `__appsignal__.py` config file: <CodeGroup> ```ruby Ruby theme={null} # __appsignal__.py appsignal = Appsignal( active=True, name="My app name", push_api_key="00000000-0000-0000-0000-000000000000" ) ``` </CodeGroup> The values of Conig options defined in this step will override values for the same Configuration options defined in previous steps. This source will be listed under `initial` in your application's config and is visible in the [Diagnose report](https://docs.appsignal.com/support/debugging.html). # Python package configuration options Source: https://docs.appsignal.com/python/configuration/options The following list includes all configuration options with the name of the environment variable and the name of the key in the configuration file. For more information on how to configure AppSignal with a configuration file or system environment variables, see our [Configuration](/python/configuration) documentation. ## Available options * Required options * [`active`](#option-active) * [`environment`](#option-environment) * [`name`](#option-name) * [`push_api_key`](#option-push_api_key) * Options * [`bind_address`](#option-bind_address) * [`ca_file_path`](#option-ca_file_path) * [`collector_endpoint`](#option-collector_endpoint) * [`cpu_count`](#option-cpu_count) * [`disable_default_instrumentations`](#option-disable_default_instrumentations) * [`dns_servers`](#option-dns_servers) * [`enable_host_metrics`](#option-enable_host_metrics) * [`enable_minutely_probes`](#option-enable_minutely_probes) * [`enable_nginx_metrics`](#option-enable_nginx_metrics) * [`enable_statsd`](#option-enable_statsd) * [`endpoint`](#option-endpoint) * [`files_world_accessible`](#option-files_world_accessible) * [`filter_attributes`](#option-filter_attributes) * [`filter_function_parameters`](#option-filter_function_parameters) * [`filter_parameters`](#option-filter_parameters) * [`filter_request_payload`](#option-filter_request_payload) * [`filter_request_query_parameters`](#option-filter_request_query_parameters) * [`filter_session_data`](#option-filter_session_data) * [`host_role`](#option-host_role) * [`hostname`](#option-hostname) * [`http_proxy`](#option-http_proxy) * [`ignore_actions`](#option-ignore_actions) * [`ignore_errors`](#option-ignore_errors) * [`ignore_namespaces`](#option-ignore_namespaces) * [`log`](#option-log) * [`log_level`](#option-log_level) * [`log_path`](#option-log_path) * [`nginx_port`](#option-nginx_port) * [`opentelemetry_port`](#option-opentelemetry_port) * [`request_headers`](#option-request_headers) * [`response_headers`](#option-response_headers) * [`revision`](#option-revision) * [`running_in_container`](#option-running_in_container) * [`send_environment_metadata`](#option-send_environment_metadata) * [`send_function_parameters`](#option-send_function_parameters) * [`send_params`](#option-send_params) * [`send_request_payload`](#option-send_request_payload) * [`send_request_query_parameters`](#option-send_request_query_parameters) * [`send_session_data`](#option-send_session_data) * [`service_name`](#option-service_name) * [`statsd_port`](#option-statsd_port) * [`working_directory_path`](#option-working_directory_path) ## active <a /> | Field | Value | | ----------------------- | -------------------------- | | Config file key | `active` | | System environment key | `APPSIGNAL_ACTIVE` | | Required | yes | | Type | Boolean (`true` / `false`) | | Default value | `false` | | Available since version | `0.1.0` | ### Description Configure AppSignal to be active or not for a given environment. If AppSignal is not active, no data is reported for the app in the specified environment. ## environment <a /> | Field | Value | | ----------------------- | ------------------- | | Config file key | `environment` | | System environment key | `APPSIGNAL_APP_ENV` | | Required | yes | | Type | `String` | | Default value | `development` | | Available since version | `0.1.0` | ### Description The environment of the app to be reported to AppSignal. <Note> **Note**: Changing the [name](#option-name) or environment of an existing app will create a new app on AppSignal.com. </Note> ## name <a /> | Field | Value | | ----------------------- | ------------------------------ | | Config file key | `name` | | System environment key | `APPSIGNAL_APP_NAME` | | Required | yes | | Type | `String` | | Default value | nil (This is unset by default) | | Available since version | `0.1.0` | ### Description Name of your application as it should be displayed on AppSignal.com. <Note> **Note**: Changing the name or [environment](#option-env) of an existing app will create a new app on AppSignal.com. </Note> ## push\_api\_key <a /> | Field | Value | | ----------------------- | ------------------------------ | | Config file key | `push_api_key` | | System environment key | `APPSIGNAL_PUSH_API_KEY` | | Required | yes | | Type | `String` | | Default value | nil (This is unset by default) | | Available since version | `0.1.0` | ### Description The organization-level authentication key to authenticate with our Push API. Read more about the [AppSignal Push API key](/appsignal/terminology#push-api-key). ## bind\_address <a /> | Field | Value | | ----------------------- | ------------------------ | | Config file key | `bind_address` | | System environment key | `APPSIGNAL_BIND_ADDRESS` | | Required | no | | Type | `String` | | Default value | `127.0.0.1` | | Available since version | `0.1.5` | ### Description A valid IPv4 address the AppSignal agent uses as a binding for its TCP and UDP servers. Use a specific address if you only want the agent to listen to requests made to that address. Set this option to `0.0.0.0` to allow to receive requests from hosts using any IP address. By default it only listens to requests made on the same host. This option is applied to all the agent servers ([StatsD](#option-enable_statsd), [OpenTelemetry](#option-enable_opentelemetry_http) and [NGINX](#option-enable_nginx_metrics)). <Note> **Agent only:** when using [an external collector](#option-collector_endpoint), this configuration option does not have any effect. </Note> ## ca\_file\_path <a /> | Field | Value | | ----------------------- | -------------------------------- | | Config file key | `ca_file_path` | | System environment key | `APPSIGNAL_CA_FILE_PATH` | | Required | no | | Type | `String` | | Default value | Packaged `cacert.pem` file path. | | Available since version | `0.1.0` | ### Description Use this option to point to another certificate file if there's a problem connecting to our API. <Note> **Note**: The specified path cannot contain Operating Specific file system abstractions, such as the homedir symbol `~` for \*NIX systems. This will be seen as a malformed path. </Note> <Note> When using [an external collector](#option-collector_endpoint), this configuration option does not have any effect on how the integration communicates with the external collector. It will still be used when communicating with AppSignal's servers. </Note> ## collector\_endpoint <a /> | Field | Value | | ----------------------- | ------------------------------ | | Config file key | `collector_endpoint` | | System environment key | `APPSIGNAL_COLLECTOR_ENDPOINT` | | Required | no | | Type | `String` | | Default value | nil (This is unset by default) | | Available since version | `1.6.0` | ### Description The address of an externally deployed [AppSignal Collector](/collector). When set, the AppSignal agent bundled with the integration will not be used, and OpenTelemetry data will be sent to the collector at this address instead. <Note> This is an **experimental** configuration option. The following functionality **will not be available** when using an external collector: * [NGINX metrics](/metrics/nginx) * [Host metrics](/metrics/host-metrics) * [StatsD metrics](/standalone-agent/statsd) The following functionality is **only available** when using an external collector: * [Logging](/logging) </Note> ## cpu\_count <a /> | Field | Value | | ----------------------- | --------------------- | | Config file key | `cpu_count` | | System environment key | `APPSIGNAL_CPU_COUNT` | | Required | no | | Type | `Float` | | Default value | `undefined` | | Available since version | `1.2.0` | ### Description The available CPU capacity of the host, in number of CPUs. This is used to calculate the CPU usage percentage in the host metrics. If not set, the agent will attempt to automatically detect this from cgroups. The number of CPUs can be a fraction, e.g. `0.5`. <Note> **Agent only:** when using [an external collector](#option-collector_endpoint), this configuration option does not have any effect. </Note> ## disable\_default\_instrumentations <a /> | Field | Value | | ----------------------- | -------------------------------------------- | | Config file key | `disable_default_instrumentations` | | System environment key | `APPSIGNAL_DISABLE_DEFAULT_INSTRUMENTATIONS` | | Required | no | | Type | `list(String)` or Boolean (`true` / `false`) | | Default value | `false` | | Available since version | `0.1.0` | ### Description Allows you to disable the automatic instrumentation of default integrations: * `aiopg` * `asyncpg` * `celery` * `django` * `flask` * `mysql` * `mysqlclient` * `psycopg` * `psycopg2` * `pymysql` * `redis` * `jinja2` * `requests` * `sqlalchemy` * `sqlite3` * `logging` <Note> When using AppSignal for Python 1.5.4 or earlier, prefix each of these names with `opentelemetry.instrumentation.`. For example, `jinja2` would be specified as `opentelemetry.instrumentation.jinja2`. </Note> Note that instrumentations are only enabled if the corresponding OpenTelemetry instrumentation library is installed. To disable all automatic instrumentations, set the value to `True`. ## dns\_servers <a /> | Field | Value | | ----------------------- | ----------------------- | | Config file key | `dns_servers` | | System environment key | `APPSIGNAL_DNS_SERVERS` | | Required | no | | Type | `list(String)` | | Default value | `[]` | | Available since version | `0.1.0` | ### Description Configure DNS servers for the AppSignal agent to use. ```sh Shell theme={null} # In the host environment export APPSIGNAL_DNS_SERVERS="8.8.8.8,8.8.4.4" ``` If you're affected by our [DNS timeouts](/support/known-issues#dns-timeouts), try setting a DNS server manually using this option that doesn't use more than **4** dots in the server name. * Acceptable values: `8.8.8.8`, `my.custom.local.server`. * Not acceptable values: `foo`, `my.awesome.custom.local.dns.server`. If the DNS server cannot be reached the agent will fall back on the host's DNS configuration and output a message in the `appsignal.log` file: `A problem occurred while setting DNS servers`. <Note> **Agent only:** when using [an external collector](#option-collector_endpoint), this configuration option does not have any effect. </Note> ## enable\_host\_metrics <a /> | Field | Value | | ----------------------- | ------------------------------- | | Config file key | `enable_host_metrics` | | System environment key | `APPSIGNAL_ENABLE_HOST_METRICS` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | \`\`true` / detected by system` | | Available since version | `0.1.0` | ### Description Set this option to `false` to disable [host metrics](/metrics/host-metrics) collection. On Heroku and Dokku host metrics are disabled by default. This is done because these systems will report inaccurate metrics from within the containers. Host metrics collection on these systems cannot be enabled. For Heroku, use the [Heroku log drain](/heroku/host-metrics) instead. <Note> **Agent only:** when using [an external collector](#option-collector_endpoint), this configuration option does not have any effect. </Note> ## enable\_minutely\_probes <a /> | Field | Value | | ----------------------- | ---------------------------------- | | Config file key | `enable_minutely_probes` | | System environment key | `APPSIGNAL_ENABLE_MINUTELY_PROBES` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `true` | | Available since version | `1.2.0` | ### Description Enables the [minutely probes](/python/instrumentation/minutely-probes) system. ## enable\_nginx\_metrics <a /> | Field | Value | | ----------------------- | -------------------------------- | | Config file key | `enable_nginx_metrics` | | System environment key | `APPSIGNAL_ENABLE_NGINX_METRICS` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `false` | | Available since version | `0.1.0` | ### Description Set to `true` to enable the NGINX metrics server. [See the NGINX metrics documentation for details.](/metrics/nginx) When enabled, the AppSignal agent will listen to a `localhost`-bound server on port 27649. If you're running several AppSignal-instrumented applications in the same server, this configuration option can only be enabled in one of them. <Note> **Agent only:** when using [an external collector](#option-collector_endpoint), this configuration option does not have any effect. </Note> ## enable\_statsd <a /> | Field | Value | | ----------------------- | -------------------------- | | Config file key | `enable_statsd` | | System environment key | `APPSIGNAL_ENABLE_STATSD` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `false` | | Available since version | `0.1.0` | ### Description Enables the [StatsD server](/standalone-agent/statsd) in the AppSignal agent. When enabled, the AppSignal agent will listen to a `localhost`-bound server on port 8125. If you're running several AppSignal-instrumented applications in the same server, this configuration option can only be enabled in one of them. <Note> **Agent only:** when using [an external collector](#option-collector_endpoint), this configuration option does not have any effect. </Note> ## endpoint <a /> | Field | Value | | ----------------------- | ----------------------------- | | Config file key | `endpoint` | | System environment key | `APPSIGNAL_PUSH_API_ENDPOINT` | | Required | no | | Type | `String` | | Default value | `https://push.appsignal.com` | | Available since version | `0.1.0` | ### Description Configure the endpoint to send data to AppSignal. This setting will not have to be changed. <Note> **Agent only:** when using [an external collector](#option-collector_endpoint), this configuration option does not have any effect. </Note> ## files\_world\_accessible <a /> | Field | Value | | ----------------------- | ---------------------------------- | | Config file key | `files_world_accessible` | | System environment key | `APPSIGNAL_FILES_WORLD_ACCESSIBLE` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `true` | | Available since version | `0.1.0` | ### Description If this is set to `true` the [AppSignal working directory](/appsignal/how-appsignal-operates#working-directory) that is created is accessible for all users (Unix permissions `0666`). This is often necessary because processes for the same app run under a different user. Set to `false` to disable this behaviour (Unix permissions `0644`). <Note> **Agent only:** when using [an external collector](#option-collector_endpoint), this configuration option does not have any effect. </Note> ## filter\_attributes <a /> | Field | Value | | ----------------------- | ----------------------------- | | Config file key | `filter_attributes` | | System environment key | `APPSIGNAL_FILTER_ATTRIBUTES` | | Required | no | | Type | `list(String)` | | Default value | `[]` | | Available since version | `1.6.0` | ### Description List of OpenTelemetry span attributes to filter with AppSignal. Matching values are replaced with `[FILTERED]`. Read more about [parameter filtering](/application/parameter-filtering). <Note> **Collector only:** this configuration option will only have an effect when using [an external collector](#option-collector_endpoint). See the [filter\_parameters](#option-filter_parameters) configuration option for filtering data when using the agent. </Note> ## filter\_function\_parameters <a /> | Field | Value | | ----------------------- | -------------------------------------- | | Config file key | `filter_function_parameters` | | System environment key | `APPSIGNAL_FILTER_FUNCTION_PARAMETERS` | | Required | no | | Type | `list(String)` | | Default value | `[]` | | Available since version | `1.6.0` | ### Description List of function parameter attributes to filter with AppSignal. Matching values are replaced with `[FILTERED]`. Read more about [parameter filtering](/application/parameter-filtering). <Note> **Collector only:** this configuration option will only have an effect when using [an external collector](#option-collector_endpoint). See the [filter\_parameters](#option-filter_parameters) configuration option for filtering data when using the agent. </Note> ## filter\_parameters <a /> | Field | Value | | ----------------------- | ----------------------------- | | Config file key | `filter_parameters` | | System environment key | `APPSIGNAL_FILTER_PARAMETERS` | | Required | no | | Type | `list(String)` | | Default value | `[]` | | Available since version | `0.1.0` | ### Description List of parameter keys that should be ignored using AppSignal filtering. Their values will be replaced with `[FILTERED]` when transmitted to AppSignal. Read more about [parameter filtering](/application/parameter-filtering). <Note> **Agent only:** when using [an external collector](#option-collector_endpoint), this configuration option does not have any effect. See the following configuration options for filtering parameters when using an external collector: * [`filter_attributes`](#option-filter_attributes) * [`filter_function_parameters`](#option-filter_function_parameters) * [`filter_request_payload`](#option-filter_request_payload) * [`filter_request_query_parameters`](#option-filter_request_query_parameters) </Note> ## filter\_request\_payload <a /> | Field | Value | | ----------------------- | ---------------------------------- | | Config file key | `filter_request_payload` | | System environment key | `APPSIGNAL_FILTER_REQUEST_PAYLOAD` | | Required | no | | Type | `list(String)` | | Default value | `[]` | | Available since version | `1.6.0` | ### Description List of request payload attributes to filter with AppSignal. Matching values are replaced with `[FILTERED]`. Read more about [parameter filtering](/application/parameter-filtering). <Note> **Collector only:** this configuration option will only have an effect when using [an external collector](#option-collector_endpoint). See the [filter\_parameters](#option-filter_parameters) configuration option for filtering data when using the agent. </Note> ## filter\_request\_query\_parameters <a /> | Field | Value | | ----------------------- | ------------------------------------------- | | Config file key | `filter_request_query_parameters` | | System environment key | `APPSIGNAL_FILTER_REQUEST_QUERY_PARAMETERS` | | Required | no | | Type | `list(String)` | | Default value | `[]` | | Available since version | `1.6.0` | ### Description List of request query parameter attributes to filter with AppSignal. Matching values are replaced with `[FILTERED]`. Read more about [parameter filtering](/application/parameter-filtering). <Note> **Collector only:** this configuration option will only have an effect when using [an external collector](#option-collector_endpoint). See the [filter\_parameters](#option-filter_parameters) configuration option for filtering data when using the agent. </Note> ## filter\_session\_data <a /> | Field | Value | | ----------------------- | ------------------------------- | | Config file key | `filter_session_data` | | System environment key | `APPSIGNAL_FILTER_SESSION_DATA` | | Required | no | | Type | `list(String)` | | Default value | `[]` | | Available since version | `0.1.0` | ### Description List of session data keys that should be ignored using AppSignal filtering. Their values will be replaced with `[FILTERED]` when transmitted to AppSignal. Read more about [session data filtering](/application/session-data-filtering). ## host\_role <a /> | Field | Value | | ----------------------- | ------------------------------ | | Config file key | `host_role` | | System environment key | `APPSIGNAL_HOST_ROLE` | | Required | no | | Type | `String` | | Default value | nil (This is unset by default) | | Available since version | `0.2.2` | ### Description Group hosts by role and generate metrics based on this role. One such metric is the `reporting_hosts` counter metric. A good role indicates what the main role of the server is, like "webserver", "processor", "api", "database", "loadbalancer", etc. <Note> **Agent only:** when using [an external collector](#option-collector_endpoint), this configuration option does not have any effect. </Note> ## hostname <a /> | Field | Value | | ----------------------- | -------------------- | | Config file key | `hostname` | | System environment key | `APPSIGNAL_HOSTNAME` | | Required | no | | Type | `String` | | Default value | detected from system | | Available since version | `0.1.0` | ### Description This overrides the server's hostname. Useful for when you're unable to set a custom hostname or when a nondescript id is generated for you on hosting services. ## http\_proxy <a /> | Field | Value | | ----------------------- | ------------------------------ | | Config file key | `http_proxy` | | System environment key | `APPSIGNAL_HTTP_PROXY` | | Required | no | | Type | `String` | | Default value | nil (This is unset by default) | | Available since version | `0.1.0` | ### Description If you require the agent to connect to the Internet via a proxy set the complete proxy URL in this configuration key. <Note> When using [an external collector](#option-collector_endpoint), this configuration option does not have any effect on how the integration communicates with the external collector. It will still be used when communicating with AppSignal's servers. </Note> ## ignore\_actions <a /> | Field | Value | | ----------------------- | -------------------------- | | Config file key | `ignore_actions` | | System environment key | `APPSIGNAL_IGNORE_ACTIONS` | | Required | no | | Type | `list(String)` | | Default value | `[]` | | Available since version | `0.1.0` | ### Description With this config option you can specify a list of actions that will be ignored by AppSignal. Everything that happens including exceptions will not be transmitted to AppSignal. This can be useful to ignore health check endpoints or other actions that you don't want to monitor. Read more about [ignoring actions](/guides/filter-data/ignore-actions). ## ignore\_errors <a /> | Field | Value | | ----------------------- | ------------------------- | | Config file key | `ignore_errors` | | System environment key | `APPSIGNAL_IGNORE_ERRORS` | | Required | no | | Type | `list(String)` | | Default value | `[]` | | Available since version | `0.1.0` | ### Description List of error classes that will be ignored. Any exception raised with this error class will not be transmitted to AppSignal. Read more about [ignoring errors](/guides/filter-data/ignore-errors). ## ignore\_namespaces <a /> | Field | Value | | ----------------------- | ----------------------------- | | Config file key | `ignore_namespaces` | | System environment key | `APPSIGNAL_IGNORE_NAMESPACES` | | Required | no | | Type | `list(String)` | | Default value | `[]` | | Available since version | `0.1.0` | ### Description List of namespaces that will be ignored. Any error raised or slow request that occurs in this namespace will not be send to AppSignal. Read more about [namespaces](/application/namespaces). ## log <a /> | Field | Value | | ----------------------- | --------------- | | Config file key | `log` | | System environment key | `APPSIGNAL_LOG` | | Required | no | | Type | `String` | | Default value | `file` | | Available since version | `0.1.0` | ### Description <Note> This option configures what logger that AppSignal's internal logging functionality will use and does not affect the [logging feature](/logging). **Note**: The [AppSignal agent](/appsignal/how-appsignal-operates), which is used by the integration, will always write to the "appsignal.log" file. </Note> Select which logger the AppSignal integration will use. Accepted values are `file` and `stdout`. See also the `log_path` configuration. * `file` (default) * Write all AppSignal logs to the file system. * `stdout` (default on [Heroku](https://heroku.com)) * Print AppSignal logs in the parent process' STDOUT instead of to a file. Useful with hosting solutions such as container systems and Heroku. <Note> When using [an external collector](#option-collector_endpoint), this configuration option does not have any effect on how the collector will emit logs. The integration will still follow this configuration option when emitting logs. </Note> ## log\_level <a /> | Field | Value | | ----------------------- | --------------------- | | Config file key | `log_level` | | System environment key | `APPSIGNAL_LOG_LEVEL` | | Required | no | | Type | `String` | | Default value | `info` | | Available since version | `0.1.0` | ### Description <Note> This option sets the severity level of AppSignal's internal logger and does not affect the [logging feature](/logging). </Note> Set the severity level of AppSignal's internal logger. If it is configured to "info" it will log all error, warning and info messages, but not log the debug messages. Setting it to the levels "debug" or "trace" is usually only needed on request from support. Setting the level to "debug"/"trace" could have a slight impact on the disk usage and IO, especially on high-traffic sites. CPU overhead is minimal with the debug option enabled. Accepted values: * error * warning * info * debug * trace <Note> When using [an external collector](#option-collector_endpoint), this configuration option does not have any effect on how the collector will emit logs. The integration will still follow this configuration option when emitting logs. </Note> ## log\_path <a /> | Field | Value | | ----------------------- | -------------------- | | Config file key | `log_path` | | System environment key | `APPSIGNAL_LOG_PATH` | | Required | no | | Type | `String` | | Default value | `/tmp` | | Available since version | `0.1.0` | ### Description <Note> This option configures the location of AppSignal's internal logging file and does not affect the [logging feature](/logging). <br /> **Note**: The specified path cannot contain Operating Specific file system abstractions, such as the homedir symbol `~` for \*NIX systems. This will be seen as a malformed path. </Note> Override the location of the path (directory) where the `appsignal.log` file can be written to. <Note> When using [an external collector](#option-collector_endpoint), this configuration option does not have any effect on how the collector will emit logs. The integration will still follow this configuration option when emitting logs. </Note> ## nginx\_port <a /> | Field | Value | | ----------------------- | ---------------------- | | Config file key | `nginx_port` | | System environment key | `APPSIGNAL_NGINX_PORT` | | Required | no | | Type | `Integer` | | Default value | `27649` | | Available since version | `1.5.4` | ### Description Configure the port on which the NGINX metrics server is exposed. When AppSignal receives NGINX metrics, it listens on a `localhost`-bound server, by default on port 27649. If you're running several AppSignal-instrumented applications in the same server with NGINX metrics enabled, use this option to configure each application to listen on a different port. <Note> **Agent only:** when using [an external collector](#option-collector_endpoint), this configuration option does not have any effect. </Note> ## opentelemetry\_port <a /> | Field | Value | | ----------------------- | ------------------------------ | | Config file key | `opentelemetry_port` | | System environment key | `APPSIGNAL_OPENTELEMETRY_PORT` | | Required | no | | Type | `Integer` | | Default value | `8099` | | Available since version | `0.2.2` | ### Description Set this option to configure the OpenTelemetry HTTP server port of the AppSignal agent process. Configure this port if another process is already running on the machine that is also using this port to avoid conflicts. <Note> **Agent only:** when using [an external collector](#option-collector_endpoint), this configuration option does not have any effect. The port to use to send OpenTelemetry data to the external collector can be specified as part of [the `collector_endpoint` configuration option](#option-collector_endpoint). </Note> ## request\_headers <a /> | Field | Value | | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------ | | Config file key | `request_headers` | | System environment key | `APPSIGNAL_REQUEST_HEADERS` | | Required | no | | Type | `list(String)` | | Default value | `["accept", "accept-charset", "accept-encoding", "accept-language", "cache-control", "connection", "content-length", "range"]` | | Available since version | `0.1.0` | ### Description The `request_headers` config option contains a list of HTTP request headers which are read and stored by the AppSignal Python package. This `request_headers` config option is an *allowlist*, which means that it will only take headers as specified by this config option. If this config option is unset it will use the AppSignal default. Following list is the AppSignal package default. ```python Python theme={null} # __appsignal__.py appsignal = Appsignal( # ...Other config opts request_headers=[ "accept", "accept-charset", "accept-encoding", "accept-language", "cache-control", "connection", "content-length", "range" ] ) ``` To customize this list, add the config option with *all headers* you want reported. All header names should be written in lowercase characters. If the header name is `X-Custom-Header`, add it to this list as `x-custom-header`. To configure AppSignal to not store any HTTP request headers on AppSignal traces, configure the option with an empty list. ```python Python theme={null} # __appsignal__.py appsignal = Appsignal( # ...Other config opts request_headers=[] ) ``` ## response\_headers <a /> | Field | Value | | ----------------------- | ---------------------------- | | Config file key | `response_headers` | | System environment key | `APPSIGNAL_RESPONSE_HEADERS` | | Required | no | | Type | `list(String)` | | Default value | `[]` | | Available since version | `1.6.0` | ### Description The `response_headers` config option contains a list of HTTP response headers which are read and stored by the AppSignal for Python package. This `response_headers` config option is an *allowlist*, which means that it will only take headers as specified by this config option. If this config option is unset, it will not report any response headers. To customize this list, add the config option with *all headers* you want reported. All header names should be written in lowercase characters. If the header name is `X-Custom-Header`, add it to this list as `x-custom-header`. <Note> **Collector only:** this configuration option will only have an effect when using [an external collector](#option-collector_endpoint). </Note> ## revision <a /> | Field | Value | | ----------------------- | ---------------------------------------------------------------------------------------------------------------- | | Config file key | `revision` | | System environment key | `APP_REVISION` | | Required | no | | Type | `String` | | Default value | nil (This is unset by default) | | Available since version | `0.1.0` | | | <ul><li>`0.2.0`: Auto detection for Render deploys.</li><li>`1.3.3`: Auto detection for Kamal deploys.</li></ul> | ### Description Set the app revision to report the currently running version of your app. AppSignal will create a deploy marker when this value changes, and tag all incoming data with the current revision. When your application is deployed using Kamal, or when it is deployed to Render, or when it is deployed to Heroku and the [Heroku Labs: Dyno Metadata](https://devcenter.heroku.com/articles/dyno-metadata) feature is enabled, the AppSignal integration will automatically detect the Git commit of the current deployment and use it as the revision. You can overwrite the automatically detected revisions in Heroku, Render or Kamal by manually setting the `revision` config option to a custom value. Read more about deploy markers in the [deploy markers topic](/application/markers/deploy-markers). <Note> When using [an external collector](#option-collector_endpoint), the revision is not automatically detected. Set this option manually to report the currently running version of your app. </Note> ## running\_in\_container <a /> | Field | Value | | ----------------------- | -------------------------------- | | Config file key | `running_in_container` | | System environment key | `APPSIGNAL_RUNNING_IN_CONTAINER` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | detected by agent | | Available since version | `0.1.0` | ### Description AppSignal expects to be running on the same machine between different deploys. Set this key to `true` if the application is running in a container, such as with Docker. Newer versions of the AppSignal integration automatically detect its container environment, so no manual configuration is necessary. If you're having trouble with the automatic detection, please [contact support](mailto:support@appsignal.com). This option is set to `true` automatically on [Heroku](http://heroku.com/). <Note> **Agent only:** when using [an external collector](#option-collector_endpoint), this configuration option does not have any effect. </Note> ## send\_environment\_metadata <a /> | Field | Value | | ----------------------- | ------------------------------------- | | Config file key | `send_environment_metadata` | | System environment key | `APPSIGNAL_SEND_ENVIRONMENT_METADATA` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `true` | | Available since version | `0.1.0` | ### Description Send environment metadata about the app. For more information please read about [environment metadata](/application/environment-metadata). <Note> **Agent only:** when using [an external collector](#option-collector_endpoint), this configuration option does not have any effect. </Note> ## send\_function\_parameters <a /> | Field | Value | | ----------------------- | ------------------------------------ | | Config file key | `send_function_parameters` | | System environment key | `APPSIGNAL_SEND_FUNCTION_PARAMETERS` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `true` | | Available since version | `1.6.0` | ### Description Whether to send function parameters to AppSignal. <Note> **Collector only:** this configuration option will only have an effect when using [an external collector](#option-collector_endpoint). See the [send\_params](#option-send_params) configuration option for sending data when not using the agent. </Note> ## send\_params <a /> | Field | Value | | ----------------------- | -------------------------- | | Config file key | `send_params` | | System environment key | `APPSIGNAL_SEND_PARAMS` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `true` | | Available since version | `0.1.0` | ### Description Whether to skip sending request parameters to AppSignal. For more information please read about [send\_params](/application/parameter-filtering) in filtering request parameters. <Note> **Agent only:** when using [an external collector](#option-collector_endpoint), this configuration option does not have any effect. See the following configuration options for sending parameters when using an external collector: * [`send_function_parameters`](#option-send_function_parameters) * [`send_request_payload`](#option-send_request_payload) * [`send_request_query_parameters`](#option-send_request_query_parameters) </Note> ## send\_request\_payload <a /> | Field | Value | | ----------------------- | -------------------------------- | | Config file key | `send_request_payload` | | System environment key | `APPSIGNAL_SEND_REQUEST_PAYLOAD` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `true` | | Available since version | `1.6.0` | ### Description Whether to send request payload to AppSignal. <Note> **Collector only:** this configuration option will only have an effect when using [an external collector](#option-collector_endpoint). See the [send\_params](#option-send_params) configuration option for sending data when not using the agent. </Note> ## send\_request\_query\_parameters <a /> | Field | Value | | ----------------------- | ----------------------------------------- | | Config file key | `send_request_query_parameters` | | System environment key | `APPSIGNAL_SEND_REQUEST_QUERY_PARAMETERS` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `true` | | Available since version | `1.6.0` | ### Description Whether to send request query parameters to AppSignal. <Note> **Collector only:** this configuration option will only have an effect when using [an external collector](#option-collector_endpoint). See the [send\_params](#option-send_params) configuration option for sending data when not using the agent. </Note> ## send\_session\_data <a /> | Field | Value | | ----------------------- | ----------------------------- | | Config file key | `send_session_data` | | System environment key | `APPSIGNAL_SEND_SESSION_DATA` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `true` | | Available since version | `0.1.0` | ### Description Set this option to `false` to not send any session data with exception traces and performance issue samples. For more information please read about [request session data filtering](/application/session-data-filtering). ## service\_name <a /> | Field | Value | | ----------------------- | ------------------------ | | Config file key | `service_name` | | System environment key | `APPSIGNAL_SERVICE_NAME` | | Required | no | | Type | `String` | | Default value | \`\` | | Available since version | `1.6.0` | ### Description The service name helps AppSignal recognize different services for traces and groups the traces automatically in a namespace based on the service name. Choose a name that fits your application, like "Web server", "Background worker", "Email service", "Authentication service", etc. <Note> **Collector only:** this configuration option will only have an effect when using [an external collector](#option-collector_endpoint). </Note> ## statsd\_port <a /> | Field | Value | | ----------------------- | ----------------------- | | Config file key | `statsd_port` | | System environment key | `APPSIGNAL_STATSD_PORT` | | Required | no | | Type | `Integer` | | Default value | `8125` | | Available since version | `0.2.2` | ### Description Set this option to configure the StatsD HTTP server port of the AppSignal agent process. Configure this port if another process is already running on the machine that is also using this port to avoid conflicts. <Note> **Agent only:** when using [an external collector](#option-collector_endpoint), this configuration option does not have any effect. </Note> ## working\_directory\_path <a /> | Field | Value | | ----------------------- | ---------------------------------- | | Config file key | `working_directory_path` | | System environment key | `APPSIGNAL_WORKING_DIRECTORY_PATH` | | Required | no | | Type | `String` | | Default value | detected by agent | | Available since version | `0.1.0` | ### Description Override the location where AppSignal for Python can store temporary files. Use this option if the default location is not suitable. See our [how AppSignal operates](/appsignal/how-appsignal-operates) page for more information about the purpose of this working directory. If you are running multiple applications using AppSignal on the same server, use this configuration option to select different working directories for every AppSignal instance, otherwise the two instances could conflict with one another. For more information on this scenario see our [running multiple applications on one host](/guides/application/multiple-applications-on-one-host) documentation. ```python Python theme={null} # __appsignal__.py appsignal = Appsignal( # Other config working_directory_path="/tmp/project_1" ) ``` <Note> **Note**: The specified path cannot contain Operating Specific file system abstractions, such as the homedir symbol `~` for \*NIX systems. This will be seen as a malformed path. </Note> <Note> **Agent only:** when using [an external collector](#option-collector_endpoint), this configuration option does not have any effect. </Note> # AppSignal Python Installation Source: https://docs.appsignal.com/python/installation This documentation walks you through the steps needed to add the AppSignal package to your application. New to AppSignal? We recommend following our [installation guide](/guides/new-application) first. ## Requirements Before you can run AppSignal, make sure your application's [Operating System is supported](/support/operating-systems). ## Installation First, [sign up](https://appsignal.com/users/sign_up) for an AppSignal account and add the AppSignal for Python integration package to your `requirements.txt` file: <CodeGroup> ```python Python theme={null} # requirements.txt appsignal ``` </CodeGroup> Then, install the package and run our automated install tool, which will create an `__appsignal__.py` file in your project: <CodeGroup> ```bash Bash theme={null} pip install -r requirements.txt python -m appsignal install ``` </CodeGroup> If the `pip` and `python` executables do not work, please use the `pip3` and `python3` executables instead. ### Manual installation You can also skip the automated tool and create the `__appsignal__.py` file manually: <CodeGroup> ```python Python theme={null} from appsignal import Appsignal appsignal = Appsignal( name="My app name", push_api_key="my-push-api-key", active=True ) ``` </CodeGroup> ### Installing instrumentation packages The AppSignal package does not automatically instrument any libraries. AppSignal offers support for a number of popular Python libraries, you can learn more about how to instrument these libraries in our Instrumentations documentation: * [Celery](/python/instrumentations/celery) * [Django](/python/instrumentations/django) * [FastAPI](/python/instrumentations/fastapi) * [Flask](/python/instrumentations/flask) * [Jinja2](/python/instrumentations/jinja2) * [MySQL](/python/instrumentations/mysql) * [PostgreSQL](/python/instrumentations/postgresql) * [Redis](/python/instrumentations/redis) * [Requests](/python/instrumentations/requests) * [Starlette](/python/instrumentations/starlette) * [WSGI/ASGI](/python/instrumentations/wsgi) ## Configuration After installing AppSignal and all necessary packages, you can read the [Configuration documentation](/python/configuration) to learn how to report data to AppSignal. [Python language]: https://www.python.org/ [OpenTelemetry]: https://opentelemetry.io/ # Custom instrumentation for Python Source: https://docs.appsignal.com/python/instrumentation AppSignal provides many ways to bring more insights in your application by adding more instrumentation or tagging the data that appears in AppSignal. * [Instrumentation](/python/instrumentation/instrumentation) * [Exception handling](/python/instrumentation/exception-handling) # Python exception handling Source: https://docs.appsignal.com/python/instrumentation/exception-handling AppSignal tries to record as many Python exceptions as possible. AppSignal is able to capture exceptions across your application with [our instrumentations](/python/instrumentations) that extend our support to many popular frameworks and background job packages. However, there may be scenarios where exceptions are raised that are not related to potential problems in your Python application, such as bots trying to automatically post forms or outdated links that might direct visitors to content that doesn't exist anymore. To avoid these errors from being raised as problems in AppSignal it's possible to add exception handling to your code or even let AppSignal completely ignore certain errors. ## Ignore errors The AppSignal configuration makes it possible to [ignore errors](/guides/filter-data/ignore-errors). By providing a list of specific errors AppSignal will not send alerts when these errors are raised. ## Exception handling Simply ignoring an error will silence notifications, but could potentially hide a bigger problem. For this reason we recommend you add exception handling with `try ... except` statements to your application. Using `try ... except` you can catch specific exceptions and add an alternative code path for when an exception occurs, such as rendering 404 pages or providing the user with more detailed error messages about what went wrong. For example, in a Django view file we can do the following: <CodeGroup> ```python Python theme={null} def show(request): try: user = Post.find(1) except RecordNotFound: return render(request, "not_found.html") ``` </CodeGroup> There's a couple of scenarios, such as when resources don't exist or when a form submission fails, that should be handled like this to provide proper HTTP responses to the end-user. If you want to report these caught errors to AppSignal, use the [`set_error`](#set_error) or [`send_error`](#send_error) helpers. ## set\_error <Compatibility /> Report errors, without having them crash your application. Using the `set_error` helper, the given error is set on the AppSignal trace, which reports the error on the trace (request / background job) to AppSignal. If you still want to track the error while catching it, you can use the `set_error` helper to add the exception to the current AppSignal trace. The error will be recorded in AppSignal, but your process will not crash. For example, in a Django view file we can do the following: <CodeGroup> ```python Python theme={null} from appsignal import set_error # In a Django view file def show(request): try: user = Post.find(1) except Post.DoesNotExist as error: set_error(error) return render(request, "not_found.html") ``` </CodeGroup> The exception will be tracked by AppSignal like any other error, and it allows you to provide custom error handling and fallbacks. <Tip> **Note:** This method only works when there is an AppSignal trace already active. Otherwise the error will be ignored. This is true in most automatically supported [instrumentations](/python/instrumentations) or when using [custom instrumentation](/python/instrumentation). Please see [`send_error`](#send_error) for sending errors without an active AppSignal trace. </Tip> ## send\_error <Compatibility /> AppSignal provides a mechanism to send errors to AppSignal without having to start a trace. This is useful for tracking errors that occur in code that's not in a web request or background job context, such as one off scripts or cron jobs. This is useful for apps that do not use our [instrumentations](/python/instrumentations) for this part of the app in which the error is raised. You can use the `send_error` method to directly send an exception to AppSignal from any place in your code without starting a trace first. <CodeGroup> ```python Python theme={null} from appsignal import send_error # In a script def perform(): try: user = Post.find(1) except Post.DoesNotExist as error: send_error(error) print("No post found!") ``` </CodeGroup> ### Additional metadata To add metadata to the sent error, use the `send_error_with_context` method. [Tags](/guides/tagging) and [other types of data customization](/guides/custom-data) can be added to the error this way. <CodeGroup> ```python Python theme={null} from appsignal import send_error_with_context, set_params # In a script def perform(): try: user = Post.find(1) except Post.DoesNotExist as error: # Using implicit current span with send_error_with_context(error): set_params({"abc": "def"}) # Using explicit `with` block span with send_error_with_context(error) as current_span: set_params({"abc": "def"}, current_span) print("No post found!") ``` </CodeGroup> # Python Custom Instrumentation Source: https://docs.appsignal.com/python/instrumentation/instrumentation Including custom instrumentation in your application can be helpful when identifying the specific lines of code causing performance problems. AppSignal for Python uses OpenTelemetry tracer objects; you can read more about Python traces in OpenTelemetry's [Python Cookbook][cookbook]. Traces are made of one or many spans. A Trace can be thought of as a directed acyclic graph (DAG) of spans: <img alt="Trace diagram" /> AppSignal specific attributes must be added to a span in order for it to be successfully parsed by AppSignal. Our set of [helper methods](#helper-methods) can be used to set these attributes. This documentation will explain how to create custom instrumentations by setting AppSignal specific attributes in your Python application's spans. ## Creating a span When adding custom instrumentation, first import the OpenTelemetry trace module in the file you want to add instrumentation to. <CodeGroup> ```python Python theme={null} from opentelemetry import trace ``` </CodeGroup> Then, using that trace module, create a new span: <CodeGroup> ```python Python theme={null} tracer = trace.get_tracer(__name__) with tracer.start_as_current_span("Span name"): # Here you can execute your app logic # And set AppSignal span details: from appsignal import set_category set_category("category.name") ``` </CodeGroup> Once you've retrieved the Span, you can use our [helper methods](#helper-method) to assign the required attributes. More information about creating and getting Spans is available in [OpenTelemetry's Python Cookbook][cookbook]. ## One offs and Serverless When running one-off scripts or serverless functions, you need to manually initialize AppSignal and stop it at the end to ensure no data is lost. The `stop` helper will gracefully kill the agent process and wait a while to ensure all data is sent to the AppSignal servers. <CodeGroup> ```python Python theme={null} appsignal = Appsignal( active=True, name="My Python App", push_api_key="YOUR_PUSH_API_KEY", ) appsignal.start() # Your code here along with the instrumentation # ... appsignal.stop() ``` </CodeGroup> ## Helper methods <Tip> The helper methods described in this section are not compatible with the [AppSignal collector](/python/configuration/collector). </Tip> The following helper methods set AppSignal specific attributes on spans that help group spans and improve how they're displayed in AppSignal. Other attributes are not supported on spans by AppSignal. ### `set_category` The span category is the name that appears in the performance event timeline for traces. It's also used to group spans together to create a breakdown per group on the sample detail page. <CodeGroup> ```python Python theme={null} from appsignal import set_category set_category("category.name") set_category("query.users") set_category("update.users") set_category("view.users") ``` </CodeGroup> The category is a string containing the child span event and group. The category should use a dot (`.`) to express the hierarchical inheritance of the event, with the highest unit last. For more information on span categories, please see the [event names guide](/api/event-names). ### `set_name` More details can be added to the span that are visible when hovering over the event in the event timeline. The span name is used to provide more information about the event, such as "Fetch users", the database from which they are fetched or the URL that was requested. <CodeGroup> ```python Python theme={null} from appsignal import set_name set_name("Fetch users") ``` </CodeGroup> If this method is not called, it will use the value with which `start_as_current_span` was called. ### `set_body` <Warning> πŸ” Do not send <strong>Personal Identifiable Information (PII)</strong> to AppSignal. Filter PII (e.g., names, emails) and use an ID, hash, or pseudonymized identifier instead. <br /> <br /> For <strong>HIPAA-covered entities</strong>, more info on signing a Business Associate Agreement (BAA) is available in our <a href="/support/business-add-ons">Business Add-Ons documentation</a>. </Warning> The span's body can include additional information about the event, like the HTTP request, the connected host, etc. Be sure to sanitize the information before adding it to the span so no Personal Identifiable Information is sent to AppSignal. This information will be visible for the span when hovering over the event timeline. To store SQL queries in the span's body, please use the [`set_sql_body` helper](#set_sql_body) instead. <CodeGroup> ```python Python theme={null} from appsignal import set_body set_body("Span body") ``` </CodeGroup> ### `set_sql_body` <Tip> Available since Python package 0.3.2. </Tip> Set a SQL query as the body of the span as it appears in the performance event timeline in the incident sample detail view. This is similar to the [`set_body` helper](#set_body), but is specialized for SQL queries. Any SQL query set as the body with this attribute will be sanitized to avoid sending PII (Personal Identifiable Information) data to our servers. See the [`set_body` helper](#set_body) for more details on how the body attribute works. When both the `set_body` and `set_sql_body` helpers are called on the same span, the `set_sql_body` helper's value is leading and the `set_body` helper's value will be ignored. <CodeGroup> ```python Python theme={null} from appsignal import set_sql_body set_body("SELECT * FROM users") ``` </CodeGroup> ### `set_root_name` <Tip> This attribute applies to the entire trace. It can be set on a child span, and does not need to be set on the uppermost parent span. This attribute can only be set once per trace. If it is set multiple times, only the attribute from one span in the trace is applied. </Tip> Every trace is grouped under an HTTP endpoint, background job worker name, or task name. We call this group the "action name". To change this action name for the entire trace, use the `set_root_name` helper. Use an action name generic enough to group all traces from this part of the app, while not reporting different names every time. Set `GET /users/:id` (where `:id` the URL parameter name) as the action name, instead of `GET /users/123` (where `123` is the actual value made in the request). The latter would report a new incident for every unique request. <CodeGroup> ```python Python theme={null} from appsignal import set_root_name set_root_name("GET /custom") # With URL parameters set_root_name("GET /users/:id") ``` </CodeGroup> #### Example Use Case Your application has an endpoint called `GET /coffee`. <CodeGroup> ```python Python theme={null} def coffee(request): return render(request, "coffee.html", {}) ``` </CodeGroup> All requests to this endpoint will generate samples called `GET /coffee`, but your endpoint handles multiple actions: `coffee?action=buy`, and `coffee?action=sell`. <img alt="Span Without Root Name" /> While they all use the `GET /coffee` endpoint, they are conceptually very different and so it would make sense for them to be grouped separately in AppSignal rather than in the same `GET /coffee` sample. To do this, you can use the `set_root_name` helper: <CodeGroup> ```python Python theme={null} from appsignal import set_root_name def coffee(request): if request.GET.action == "buy": set_root_name("Buy coffee") # Buy coffee... elif request.GET.action == "sell": set_root_name("Sell coffee") # Sell coffee... return render(request, "coffee.html", {}) ``` </CodeGroup> Using `set_root_name` will change the name of the root span, grouping the samples for the requests `coffee?action=buy` and `coffee?action=sell` into separate actions: <img alt="Root Name Span" /> ## Other trace data To customize the data stored on the trace even further, please see our [Tagging](/guides/tagging) and [Data Customization](/guides/custom-data) guides to add tags, parameters, session data, custom data and more. [cookbook]: https://opentelemetry.io/docs/instrumentation/python/cookbook/ # Minutely probes Source: https://docs.appsignal.com/python/instrumentation/minutely-probes <VersionRequirements /> Minutely probes are a mechanism to periodically send custom metrics to AppSignal. In minutely intervals from when the probe was first created, a user-defined function can be called in which you can capture metrics to send them to AppSignal. Minutely probe functions are ran asynchronously. You can enable or disable minutely probes entirely with the [`enable_minutely_probes`](/python/configuration/options#option-enable_minutely_probes) config option. ## Registering probes To track custom metrics from your application, you can add your own probes. To register a probe, you must call the `probes.register()` method with two arguments: a probe name, and a function to be called once every minute. <CodeGroup> ```python Python theme={null} from appsignal import probes, set_gauge def set_database_size_gauge(): set_gauge("database_size", 10) probes.register("database", set_database_size_gauge) ``` </CodeGroup> To ensure all minutely probes are ran in a timely manner, it is important to avoid blocking for long periods inside a minutely probe function. ## Stateful probes A probe function can keep state in between executions by accepting it as an argument and returning it. This is useful to keep track of how values change over time: <CodeGroup> ```python Python theme={null} from appsignal import probes, set_gauge def set_user_signups_gauge(previous_user_count): current_user_count = User.objects.all().count() if previous_user_count is not None: set_gauge("user_signups", current_user_count - previous_user_count) return current_user_count probes.register("user_signups", set_user_signups_gauge) ``` </CodeGroup> The first time the minutely probe is called, `None` will be passed as the argument. In successive invocations, the value returned by the previous invocation will be passed to it as an argument. # Python Instrumentations Source: https://docs.appsignal.com/python/instrumentations This page lists all the libraries that AppSignal for Python supports. OpenTelemetry instrumentations that are not listed here may not work, report incomplete data or show up as "unknown" in the AppSignal interface. ## Supported Python Libraries * [Celery](/python/instrumentations/celery) * [Django](/python/instrumentations/django) * [FastAPI](/python/instrumentations/fastapi) * [Flask](/python/instrumentations/flask) * [Jinja2](/python/instrumentations/jinja2) * [MySQL](/python/instrumentations/mysql) * [Pika](/python/instrumentations/pika) * [PostgreSQL](/python/instrumentations/postgresql) * [Redis](/python/instrumentations/redis) * [Requests](/python/instrumentations/requests) * [Starlette](/python/instrumentations/starlette) * [SQLAlchemy](/python/instrumentations/sqlalchemy) * [SQLite](/python/instrumentations/sqlite) * [WSGI/ASGI](/python/instrumentations/wsgi) - [Celery](/python/instrumentations/celery) - [Django](/python/instrumentations/django) - [FastAPI](/python/instrumentations/fastapi) - [Flask](/python/instrumentations/flask) - [Jinja2](/python/instrumentations/jinja2) - [MySQL](/python/instrumentations/mysql) - [Pika](/python/instrumentations/pika) - [PostgreSQL](/python/instrumentations/postgresql) - [Redis](/python/instrumentations/redis) - [Requests](/python/instrumentations/requests) - [SQLAlchemy](/python/instrumentations/sqlalchemy) - [SQLite](/python/instrumentations/sqlite) - [Starlette](/python/instrumentations/starlette) - [WSGI/ASGI](/python/instrumentations/wsgi) # Celery Instrumentation Source: https://docs.appsignal.com/python/instrumentations/celery <VersionRequirements /> [Celery](https://github.com/celery/celery) is a simple, flexible, and reliable distributed system to process vast amounts of messages, while providing operations with the tools required to maintain such a system. ## Installation <Note> 🐍 Don't forget to [install the AppSignal for Python package](/python/installation) in your application first. </Note> First, install the `opentelemetry-instrumentation-celery` package. We also recommend installing the [Redis](/python/instrumentations/redis) instrumentation package. To add both instrumentation packages to your project, add the following lines to your `requirements.txt` file: <CodeGroup> ```python Python theme={null} <PythonDisableInstrumentations /> # requirements.txt opentelemetry-instrumentation-celery opentelemetry-instrumentation-redis ``` </CodeGroup> ## Setup Celery requires some extra setup, as it's an application component that's started separately. As shown in the example below, the `appsignal` module needs to be imported in the main file used to start Celery, and the `appsignal.start()` method needs to be called from a method with the `@worker_process_init.connect` decorator. In the example below, this initialization takes place in the `tasks.py` file. This file may be named differently in your application. <CodeGroup> ```python Python theme={null} # tasks.py # Import this file import appsignal from celery import Celery # Import this file from celery.signals import worker_process_init # Add the init_celery_tracing method with its annotation @worker_process_init.connect(weak=False) def init_celery_tracing(*args, **kwargs): appsignal.start() app = Celery('tasks', broker='redis://localhost') @app.task def slow_task(): # Do things ``` </CodeGroup> # Django Instrumentation Source: https://docs.appsignal.com/python/instrumentations/django <VersionRequirements /> [Django](https://www.djangoproject.com/) is a high-level Python web framework that encourages rapid development and clean, pragmatic design. ## Installation <Note> 🐍 Don't forget to [install the AppSignal for Python package](/python/installation) in your application first. </Note> First, install the `opentelemetry-instrumentation-django` package, as well as the `opentelemetry-instrumentation-wsgi` and `opentelemetry-instrumentation-asgi` packages. To add these packages to your project, add the following line to your `requirements.txt` file: <CodeGroup> ```python Python theme={null} # requirements.txt opentelemetry-instrumentation-django opentelemetry-instrumentation-wsgi opentelemetry-instrumentation-asgi ``` </CodeGroup> To instrument queries performed via the Django ORM, install the instrumentation for the SQL database that your application uses: * [MySQL](/python/instrumentations/mysql) * [PostgreSQL](/python/instrumentations/postgresql) * [SQLite](/python/instrumentations/sqlite) <Note> The AppSignal for Python integration will automatically use this instrumentation when the corresponding package is installed. To disable this instrumentation without uninstalling the package, use the [`disable_default_instrumentations` configuration option](/python/configuration/options#option-disable_default_instrumentations). </Note> ## Development setup Django requires some extra setup, as it's usually the first thing started in an app. As shown in the example below, the `appsignal` module needs to be imported in the `manage.py` file. Then in the `main` method, the `appsignal.start` method needs to be called to initialize the instrumentation configured in the `__appsignal__.py` file. <CodeGroup> ```python Python theme={null} # manage.py #!/usr/bin/env python """Django's command-line utility for administrative tasks.""" import os import sys # Add this import statement import appsignal def main(): """Run administrative tasks.""" os.environ.setdefault('DJANGO_SETTINGS_MODULE', '<YOUR_APP_NAME_HERE>.settings') # Add this method call appsignal.start() try: from django.core.management import execute_from_command_line except ImportError as exc: raise ImportError( "Couldn't import Django. Are you sure it's installed and " "available on your PYTHONPATH environment variable? Did you " "forget to activate a virtual environment?" ) from exc execute_from_command_line(sys.argv) if __name__ == '__main__': main() ``` </CodeGroup> ## Production setup (WSGI/ASGI) In production, it is recommended to run Django using a WSGI or ASGI server, such as Gunicorn or Uvicorn. In this scenario, the `manage.py` file that is modified in the development setup above is never called. To instrument your application when started as a WSGI or ASGI server, add the following to your project's `wsgi.py` file, if using a WSGI server: <CodeGroup> ```python Python theme={null} # wsgi.py import os # Add this import statement import appsignal from django.core.wsgi import get_wsgi_application os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'your_app.settings') # Add this method call appsignal.start() application = get_wsgi_application() ``` </CodeGroup> Or to your project's `asgi.py` file, if using an ASGI server: <CodeGroup> ```python Python theme={null} # asgi.py import os # Add this import statement import appsignal from django.core.asgi import get_asgi_application os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'your_app.settings') # Add this method call appsignal.start() application = get_asgi_application() ``` </CodeGroup> ## Features By default, the Django instrumentation reports incoming request parameters, like query strings and routing parameters. <Warning> πŸ” Do not send <strong>Personal Identifiable Information (PII)</strong> to AppSignal. Filter PII (e.g., names, emails) and use an ID, hash, or pseudonymized identifier instead. <br /> <br /> For <strong>HIPAA-covered entities</strong>, more info on signing a Business Associate Agreement (BAA) is available in our <a href="/support/business-add-ons">Business Add-Ons documentation</a>. </Warning> # FastAPI Instrumentation Source: https://docs.appsignal.com/python/instrumentations/fastapi <VersionRequirements /> [FastAPI](https://fastapi.tiangolo.com/) is a modern, high-performance web framework for building APIs with Python. ## Installation <Note> 🐍 Don't forget to [install the AppSignal for Python package](/python/installation) in your application first. </Note> First, install the `opentelemetry-instrumentation-fastapi` package. To add it to your project, add the following line to your `requirements.txt` file: <CodeGroup> ```python Python theme={null} # requirements.txt opentelemetry-instrumentation-fastapi ``` </CodeGroup> ## Setup Start AppSignal and define your FastAPI application. Then use the `FastAPIInstrumentor` to instrument your FastAPI application: <CodeGroup> ```python Python theme={null} # app.py from fastapi import FastAPI from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor import appsignal appsignal.start() app = FastAPI() # ... your app's code goes here ... FastAPIInstrumentor().instrument_app(app) ``` </CodeGroup> # Flask Instrumentation Source: https://docs.appsignal.com/python/instrumentations/flask <VersionRequirements /> [Flask](https://flask.palletsprojects.com/) is a lightweight web framework for Python that enables the development of web applications with simplicity and flexibility. ## Installation <Note> 🐍 Don't forget to [install the AppSignal for Python package](/python/installation) in your application first. </Note> First, install the `opentelemetry-instrumentation-flask` package. To add it to your project, add the following line to your `requirements.txt` file: <CodeGroup> ```python Python theme={null} <PythonDisableInstrumentations /> # requirements.txt opentelemetry-instrumentation-flask ``` </CodeGroup> ## Setup It's necessary to import **and start** the AppSignal client **before the Flask library is imported**. This ensures that the application instance is created with the automatic instrumentation applied. <CodeGroup> ```python Python theme={null} # app.py import appsignal appsignal.start() from flask import Flask # noqa: E402 app = Flask(__name__) # your app code ``` </CodeGroup> # Jinja2 Instrumentation Source: https://docs.appsignal.com/python/instrumentations/jinja2 <VersionRequirements /> ## Installation <Note> 🐍 Don't forget to [install the AppSignal for Python package](/python/installation) in your application first. </Note> Install the `opentelemetry-instrumentation-jinja2` package. To add it to your project, add the following line to your `requirements.txt` file: <CodeGroup> ```python Python theme={null} <PythonDisableInstrumentations /> # requirements.txt opentelemetry-instrumentation-jinja2 ``` </CodeGroup> # MySQL Instrumentation Source: https://docs.appsignal.com/python/instrumentations/mysql ## Installation <Note> 🐍 Don't forget to [install the AppSignal for Python package](/python/installation) in your application first. </Note> The installation instructions differ based on the MySQL adapter package you are using: * [`mysql`](#using-mysql) (from the `mysql-connector-python` package) * [`mysqlclient`](#using-mysqlclient) * [`pymysql`](#using-pymysql) <Warning> When using [SQLAlchemy](/python/instrumentations/sqlalchemy), **do not** install these instrumentation packages. The instrumentation for SQLAlchemy will automatically instrument queries to the underlying database. Installing both instrumentation packages will result in duplicate events. </Warning> ### Using `mysql` <Compatibility /> When using the `mysql-connector-python` MySQL adapter package (which is imported as `mysql`), install the `opentelemetry-instrumentation-mysql` package. To add it to your project, add the following line to your `requirements.txt` file: <CodeGroup> ```python Python theme={null} <PythonDisableInstrumentations /> # requirements.txt opentelemetry-instrumentation-mysql ``` </CodeGroup> ### Using `mysqlclient` <Compatibility /> When using the `mysqlclient` MySQL adapter package, install the `opentelemetry-instrumentation-mysqlclient` package. To add it to your project, add the following line to your `requirements.txt` file: <CodeGroup> ```python Python theme={null} # requirements.txt opentelemetry-instrumentation-mysqlclient ``` </CodeGroup> ### Using `pymysql` <Compatibility /> When using the `pymysql` MySQL adapter package, install the `opentelemetry-instrumentation-pymysql` package. To add it to your project, add the following line to your `requirements.txt` file: <CodeGroup> ```python Python theme={null} # requirements.txt opentelemetry-instrumentation-pymysql ``` </CodeGroup> # Pika Source: https://docs.appsignal.com/python/instrumentations/pika <VersionRequirements /> Pika is a Python implementation of the AMQP 0-9-1 protocol. The AppSignal for Python integration for [Pika](https://pika.readthedocs.io/en/stable/) instruments the sending and receiving of messages in your application. ## Installation <Note> 🐍 Don't forget to [install the AppSignal for Python package](/python/installation) in your application first. </Note> First, install the `opentelemetry-instrumentation-pika` package. <CodeGroup> ```python Python theme={null} # requirements.txt opentelemetry-instrumentation-pika ``` </CodeGroup> If you run your consumers as separate processes, make sure to also import `appsignal` and call `appsignal.start()` before starting the Pika consumer processes, so that AppSignal can instrument the consumers' message processing. ## Features When using the Pika integration, AppSignal will create a performance sample for each message that is sent or received by a consumer. When a message is sent or received in an instrumented context, such as a web request or background job, AppSignal will display an event in the performance sample's event timeline representing the message sending or receiving. # PostgreSQL Instrumentation Source: https://docs.appsignal.com/python/instrumentations/postgresql ## Installation <Note> 🐍 Don't forget to [install the AppSignal for Python package](/python/installation) in your application first. </Note> The installation instructions differ based on the PostgreSQL adapter package you are using: * [`aiopg`](#using-aiopg) * [`asyncpg`](#using-asyncpg) * [`psycopg2`](#using-psycopg2) * [`psycopg`](#using-psycopg) (version 3) <Warning> When using [SQLAlchemy](/python/instrumentations/sqlalchemy), **do not** install these instrumentation packages. The instrumentation for SQLAlchemy will automatically instrument queries to the underlying database. Installing both instrumentation packages will result in duplicate events. </Warning> ### Using `aiopg` <Compatibility /> When using the `aiopg` PostgreSQL adapter package, install the `opentelemetry-instrumentation-aiopg` package. To add it to your project, add the following line to your `requirements.txt` file: <CodeGroup> ```python Python theme={null} <PythonDisableInstrumentations /> # requirements.txt opentelemetry-instrumentation-aiopg ``` </CodeGroup> ### Using `asyncpg` <Compatibility /> When using the `asyncpg` PostgreSQL adapter package, install the `opentelemetry-instrumentation-asyncpg` package. To add it to your project, add the following line to your `requirements.txt` file: <CodeGroup> ```python Python theme={null} # requirements.txt opentelemetry-instrumentation-asyncpg ``` </CodeGroup> ### Using `psycopg2` <Compatibility /> When using the `psycopg2` PostgreSQL adapter package, install the `opentelemetry-instrumentation-psycopg2` package. To add it to your project, add the following line to your `requirements.txt` file: <CodeGroup> ```python Python theme={null} # requirements.txt opentelemetry-instrumentation-psycopg2 ``` </CodeGroup> ### Using `psycopg` <Compatibility /> When using the `psycopg` (version 3) PostgreSQL adapter package, install the `opentelemetry-instrumentation-psycopg` package. To add it to your project, add the following line to your `requirements.txt` file: <CodeGroup> ```python Python theme={null} # requirements.txt opentelemetry-instrumentation-psycopg ``` </CodeGroup> # Redis Instrumentation Source: https://docs.appsignal.com/python/instrumentations/redis <VersionRequirements /> The Python interface to the [Redis](https://pypi.org/project/redis/) key-value store. ## Installation <Note> 🐍 Don't forget to [install the AppSignal for Python package](/python/installation) in your application first. </Note> Install the `opentelemetry-instrumentation-redis` package. To add it to your project, add the following line to your `requirements.txt` file: <CodeGroup> ```python Python theme={null} <PythonDisableInstrumentations /> # requirements.txt opentelemetry-instrumentation-redis ``` </CodeGroup> # Requests Instrumentation Source: https://docs.appsignal.com/python/instrumentations/requests <VersionRequirements /> ## Installation <Note> 🐍 Don't forget to [install the AppSignal for Python package](/python/installation) in your application first. </Note> Install the `opentelemetry-instrumentation-requests` package. To add it to your project, add the following line to your `requirements.txt` file: <CodeGroup> ```python Python theme={null} <PythonDisableInstrumentations /> # requirements.txt opentelemetry-instrumentation-requests ``` </CodeGroup> # SQLAlchemy Instrumentation Source: https://docs.appsignal.com/python/instrumentations/sqlalchemy <VersionRequirements /> ## Installation <Note> 🐍 Don't forget to [install the AppSignal for Python package](/python/installation) in your application first. </Note> <Warning> When using SQLAlchemy, **do not** install the instrumentation packages for the underlying database adapter (such as those for [MySQL](/python/instrumentations/mysql), [PostgreSQL](/python/instrumentations/postgresql) or [SQLite](/python/instrumentations/sqlite)). The instrumentation for SQLAlchemy will automatically instrument queries to the underlying database. Installing both instrumentation packages will result in duplicate events. </Warning> Install the `opentelemetry-instrumentation-sqlalchemy` package. To add it to your project, add the following line to your `requirements.txt` file: <CodeGroup> ```python Python theme={null} <PythonDisableInstrumentations /> # requirements.txt opentelemetry-instrumentation-sqlalchemy ``` </CodeGroup> # SQLite Instrumentation Source: https://docs.appsignal.com/python/instrumentations/sqlite <VersionRequirements /> ## Installation <Note> 🐍 Don't forget to [install the AppSignal for Python package](/python/installation) in your application first. </Note> Install the `opentelemetry-instrumentation-sqlite3` package. To add it to your project, add the following line to your `requirements.txt` file: <CodeGroup> ```python Python theme={null} <PythonDisableInstrumentations /> # requirements.txt opentelemetry-instrumentation-sqlite3 ``` </CodeGroup> # Starlette Instrumentation Source: https://docs.appsignal.com/python/instrumentations/starlette <VersionRequirements /> [Starlette](https://www.starlette.io/) is a lightweight, high-performance web framework for building asynchronous Python applications. ## Installation <Note> 🐍 Don't forget to [install the AppSignal for Python package](/python/installation) in your application first. </Note> First, install the `opentelemetry-instrumentation-starlette` package. To add it to your project, add the following line to your `requirements.txt` file: <CodeGroup> ```python Python theme={null} # requirements.txt opentelemetry-instrumentation-starlette ``` </CodeGroup> ## Setup Start AppSignal and define your Starlette application. Then use the `StarletteInstrumentor` to instrument your Starlette application: <CodeGroup> ```python Python theme={null} # app.py from starlette.applications import Starlette from opentelemetry.instrumentation.starlette import StarletteInstrumentor import appsignal appsignal.start() # ... your application's code goes here ... app = Starlette( # ... ) StarletteInstrumentor().instrument_app(app) ``` </CodeGroup> # WSGI/ASGI Instrumentation Source: https://docs.appsignal.com/python/instrumentations/wsgi The WSGI and ASGI standards provide a common layer for the development of web frameworks and servers in Python. Most popular Python web frameworks follow these standards, allowing for any Python web application to be deployed with any Python web server. <Tip> ASGI support was added in version `0.1.4` of the AppSignal for Python package. </Tip> AppSignal supports instrumentation for generic WSGI and ASGI web applications through OpenTelemetry. <Tip> AppSignal also supports popular web frameworks directly, such as [Django](/python/instrumentations/django), [Flask](/python/instrumentations/flask), [FastAPI](/python/instrumentations/fastapi) or [Starlette](/python/instrumentations/starlette). If you're using a web framework we support directly, follow the instructions for that framework instead of the generic WSGI/ASGI instructions on this page. </Tip> ## Installation <Note> 🐍 Don't forget to [install the AppSignal for Python package](/python/installation) in your application first. </Note> First, install either the `opentelemetry-instrumentation-wsgi` or the `opentelemetry-instrumentation-asgi` package, depending the gateway interface used in the application. To add it to your project, add the following line to your `requirements.txt` file: <CodeGroup> ```python Python theme={null} # requirements.txt # For a WSGI application: opentelemetry-instrumentation-wsgi # For an ASGI application: opentelemetry-instrumentation-asgi ``` </CodeGroup> ## Setup In your application's entry point (usually named `main.py` or `app.py`), before your application is initialised, call `appsignal.start()` to start your application: <CodeGroup> ```python Python theme={null} import appsignal appsignal.start() # ... the rest of your code goes here ... ``` </CodeGroup> Then, import `OpenTelemetryMiddleware` from the corresponding OpenTelemetry instrumentation, and wrap your application with it: <CodeGroup> ```python Python theme={null} # For a WSGI application: from opentelemetry.instrumentation.wsgi import OpenTelemetryMiddleware # For an ASGI application: from opentelemetry.instrumentation.asgi import OpenTelemetryMiddleware my_app = # ... your WSGI/ASGI application goes here ... my_app = OpenTelemetryMiddleware(my_app) ``` </CodeGroup> ## Grouping routes By default, a generic WSGI or ASGI instrumentation will not have the necessary context to understand how routing is structured in your application. As such, the performance samples that AppSignal receives will not be grouped correctly. You must add routing information to the OpenTelemetry span manually. One way to do so is by following OpenTelemetry's HTTP semantic conventions, setting the `http.route` attribute in your route handlers: <CodeGroup> ```python Python theme={null} from opentelemetry.trace import get_current_span def get_user_route_handler(): get_current_span().set_attribute("http.route", "/users/:user_id") # ... your route handler goes here ... ``` </CodeGroup> AppSignal will automatically use the value of this attribute and use it to group requests, along with the request method. For example, a GET request that is handled by this method will appear as `GET /users/:user_id` in the AppSignal performance samples panel. If you prefer to group requests in some other way (for example, by referring to the method or class that implements them) you can use the `appsignal.root_name` attribute: <CodeGroup> ```python Python theme={null} from opentelemetry.trace import get_current_span class UserHandlers: def show(): get_current_span().set_attribute("appsignal.root_name", "UserHandlers#show") # ... your route handler goes here ... ``` </CodeGroup> By using `appsignal.root_name`, the request method will not be used. The value provided (in this case, `UserHandlers#show`) will be used to group all requests handled by this method. # Render dashboards Source: https://docs.appsignal.com/render/dashboards Learn what each automated Render dashboard means. <Tip> **Tip:** Make sure you have completed the [Render setup](/render/setup) and have a working Metrics Stream destination before continuing with this section. </Tip> Once a Metrics Stream is set up, these dashboards are generated automatically as Magic dashboards. No further action is required. Depending on the Render services your workspace uses, you may see: * [HTTP dashboard](#http-dashboard) * [Postgres dashboard](#postgres-dashboard) * [Key Value dashboard](#key-value-dashboard) ## HTTP dashboard The HTTP dashboard shows request volume and latency for Render web services. Render aggregates these metrics across all instances of a service, so each line corresponds to a host and status code combination across the whole service rather than a specific replica. **HTTP requests**: Number of HTTP requests received, broken down by host and status code. It uses the following metric: `render.service.http.requests.total`. **HTTP latency**: Response latency at the p50, p95 and p99 percentiles, broken down by host and status code. It uses the following metric: `render.service.http.requests.latency`. <Frame> <img alt="Screenshot of the Render HTTP magic dashboard in AppSignal" /> </Frame> ## Postgres dashboard The Postgres dashboard shows information about [Render Postgres](https://render.com/docs/postgresql) instances connected to your workspace. **Connections**: Active connections per database, compared against the connection limit. It uses the following metrics: `render.postgres.connections` and `render.postgres.connection.limit`. **Storage size**: Database size and indexes size per database. It uses the following metrics: `render.postgres.database.size` and `render.postgres.indexes.size`. **Transaction volume**: Number of transactions over time. It uses the following metric: `render.postgres.transaction.volume`. **Sequential table scans**: Sequential scans per database. A high number of sequential scans can indicate missing indexes. It uses the following metric: `render.postgres.table.scans`. **Transaction exhaustion**: Per-database transaction ID exhaustion, useful for monitoring vacuuming health. It uses the following metric: `render.postgres.transaction.exhaustion`. **Slow locks**: Number of locks that exceeded the slow threshold. It uses the following metric: `render.postgres.slow.lock.count`. **Slow lock wait time**: Time spent waiting on slow locks. It uses the following metric: `render.postgres.slow.lock.time`. **Replication lag**: Replication delay per replica host. It uses the following metrics: `render.postgres.replication.lag` and `render.postgres.replication.apply.lag`. <Frame> <img alt="Screenshot of the Render Postgres magic dashboard in AppSignal" /> </Frame> ## Key Value dashboard The Key Value dashboard shows connection metrics for [Render Key Value](https://render.com/docs/key-value) (Valkey/Redis) services. **Connections**: Active connections, compared against the connection limit. It uses the following metrics: `render.keyvalue.connections` and `render.keyvalue.connection.limit`. CPU, memory, disk and network usage for Key Value services are reported as host metrics and appear in the ["host metrics" section](https://appsignal.com/redirect-to/app?to=host_metrics) instead of on this dashboard. <Frame> <img alt="Screenshot of the Render Key Value magic dashboard in AppSignal" /> </Frame> # Render deploy markers Source: https://docs.appsignal.com/render/deploy-markers <Compatibility /> When deploying an application using Render, it will populate the `RENDER_GIT_COMMIT` environment variable with the SHA of the git commit being deployed. AppSignal will automatically set the `revision` config option to the value of the `RENDER_GIT_COMMIT` system environment variable. This will automatically report new deploys when the Render app is deployed. # Setup Source: https://docs.appsignal.com/render/setup Learn how to set up Render for AppSignal. AppSignal's Render metrics and dashboards are available for [Render](https://render.com) workspaces and can be configured in just a few steps using Render's [Metrics Stream](https://render.com/docs/metrics-streams) feature. <Tip> Render's Metrics Stream feature requires the Render workspace to be on the Pro plan or higher. </Tip> <Tip> Please note that Render's Metrics Stream is configured per workspace, while AppSignal's app-level push API key is per app. Choose the AppSignal app that should receive metrics for the whole Render workspace before you continue. If your Render workspace runs multiple applications, metrics from all Render services will be sent to the AppSignal app that owns the configured key, and currently cannot be split per service. </Tip> If you also want to access and manage your Render logs in AppSignal, you should additionally configure the [Render Log Stream for AppSignal Logging](/logging/platforms/render). You only have to set up this metrics stream once per workspace and it will provide data for features such as host metrics and [magic dashboards](/render/dashboards). To configure Render to send OpenTelemetry metrics to AppSignal, follow the steps below: 1. From your workspace's home in the Render Dashboard, select **Integrations > Observability** in the left sidebar, then select **+ Add destination** under **Metrics Stream**. <Frame> <img alt="Screenshot of the Observability page in the Render Dashboard" /> </Frame> 2. Choose **Custom** as the **Observability provider**. 3. In the **Endpoint** field, enter the URL of your [Hosted Collector](/collector/hosted-vs-self-hosted), which you can find in your organization's [Hosted Collectors settings](https://appsignal.com/redirect-to/organization?to=admin/hosted_collectors). 4. In the **Token** field, enter your AppSignal app-level push API key, which can be found in [App settings](https://appsignal.com/redirect-to/app?to=api_keys\&key_tab=app). 5. Select **Add destination**. <Frame> <img alt="Screenshot of the "Add Metrics Stream" form filled in with AppSignal's hosted collector URL and an app-level push API key" /> </Frame> After this, Render will create a metrics stream and send service metrics to AppSignal. CPU, memory, disk capacity, disk I/O and network I/O metrics will appear as [host metrics](/metrics/host-metrics) in your AppSignal app, alongside any other host metrics. HTTP, [Render Postgres](https://render.com/docs/postgresql) and [Render Key Value](https://render.com/docs/key-value) metrics power the [magic dashboards](/render/dashboards) that appear in your AppSignal app. If you do not see metrics yet, wait a few minutes and refresh the page. <Frame> <img alt="Screenshot of AppSignal's host metrics page showing Render services" /> </Frame> To report deploys from a Render service, install the AppSignal integration for your language. AppSignal will pick up Render's `RENDER_GIT_COMMIT` environment variable automatically; see [Render support](/application/markers/deploy-markers#render-support) in our deploy markers documentation for details. # Discover AppSignal Source: https://docs.appsignal.com/resources Helpful AppSignal resources: blog, support, and platform status. Quick links to AppSignal resources outside of the documentation. <CardGroup> <Card title="Blog" icon="newspaper" href="https://blog.appsignal.com"> Tutorials, deep dives, and engineering stories from the AppSignal team. </Card> <Card title="Learning Center" icon="book-open" href="https://www.appsignal.com/learning-center"> Practical guides and lessons to help you get more out of AppSignal. </Card> <Card title="Support" icon="life-ring" href="mailto:support@appsignal.com"> Get in touch with our support team for help with your account or setup. </Card> <Card title="Status" icon="signal-bars" href="https://status.appsignal.com"> Real-time status of AppSignal services and incident history. </Card> </CardGroup> # AppSignal for Ruby Source: https://docs.appsignal.com/ruby AppSignal supports the [Ruby language][ruby-lang] with a [Ruby gem][appsignal-gem]. The gem supports many frameworks and gems out-of-the-box, but some gems and frameworks might require custom instrumentation. It's also possible to add custom instrumentation to your application to gain even more insights into the performance of your code. ## Configuration In this topic, we'll explain how to configure AppSignal. You'll learn what can be configured in the Ruby gem, what's the minimal configuration needed, and how the configuration is loaded. See our [configuration](/ruby/configuration) documentation for the complete configuration documentation of the AppSignal gem. ## Integrations The AppSignal Ruby gem integrates with many frameworks, including Rails, Sinatra, Padrino, Grape, and more: * [Active Job](/ruby/integrations/active-job) * [Capistrano](/ruby/integrations/capistrano) * [DataMapper](/ruby/integrations/datamapper) * [Delayed::Job](/ruby/integrations/delayed-job) * [Garbage Collection](/ruby/integrations/garbage-collection) * [Global VM Lock](/ruby/integrations/global-vm-lock) * [Grape](/ruby/integrations/grape) * [GraphQL](/ruby/integrations/graphql) * [Hanami](/ruby/integrations/hanami) * [HTTP.rb](/ruby/integrations/http) * [MongoDB](/ruby/integrations/mongodb) * [Multiple Rack libraries](/ruby/integrations/rack-libraries) * [Net::HTTP](/ruby/integrations/net-http) * [Padrino](/ruby/integrations/padrino) * [Puma](/ruby/integrations/puma) * [Que](/ruby/integrations/que) * [Rack](/ruby/integrations/rack) * [Rake](/ruby/integrations/rake) * [Redis](/ruby/integrations/redis) * [Resque](/ruby/integrations/resque) * [Ruby on Rails](/ruby/integrations/rails) * [Ruby VM](/ruby/integrations/ruby-vm) * [Sequel](/ruby/integrations/sequel) * [Shoryuken](/ruby/integrations/shoryuken) * [Sidekiq](/ruby/integrations/sidekiq) * [Solid Queue](/ruby/integrations/solidqueue) * [Sinatra](/ruby/integrations/sinatra) * [ViewComponent](/ruby/integrations/view-component) * [Webmachine](/ruby/integrations/webmachine) ## Custom instrumentation Add custom instrumentation to your application, or create your own integrations with AppSignal. See the [instrumentation](/ruby/instrumentation) topic for more details. ## Command line tools The AppSignal Ruby gem ships with several command line tools. These tools make it easier to install AppSignal in an application, send deploy notifications, and diagnose any problems with the installation. See our [command line tools](/ruby/command-line) documentation for a full list of all the available commands. ## Ruby implementation support ### Ruby (MRI) We currently support [Ruby `2.7.0+` and higher](/support/maintenance-policy). If you require support for older versions of Ruby, you can use an older version of the AppSignal gem. However, note that we do not provide full support for older versions of the gem. ### JRuby JRuby support is [available](https://blog.appsignal.com/2018/02/14/ruby-gem-2-5.html) in version `2.5.0` and higher of the AppSignal Ruby gem. To use JRuby on Alpine Linux, make sure to upgrade to Ruby gem `2.8.0` or newer. Also, check if your [Operating System is supported](/support/operating-systems) in combination with JRuby. [ruby-lang]: https://www.ruby-lang.org/ [appsignal-gem]: https://rubygems.org/gems/appsignal # AppSignal for Ruby: Command-line tools Source: https://docs.appsignal.com/ruby/command-line The [AppSignal Ruby gem][gem] ships with several command-line tools. These tools make it easier to install AppSignal in an application, send deploy notifications and diagnose any problems with the installation. ## Install A command-line tool to install AppSignal in your Ruby application. Read more about the [appsignal install][cli-install] command-line tool. ## Diagnose A self-diagnostic tool that can be used to debug the installation and configuration of your AppSignal integration. It is one of the first tools that our support team requests you to run when debugging an issue. Read more about the [appsignal diagnose][cli-diagnose] command-line tool. ## Demo A command-line tool that sends demonstration samples to AppSignal. When the tool is run, it sends an error and performance sample from your machine to AppSignal. Read more about the [appsignal demo][cli-demo] command-line tool. [gem]: https://github.com/appsignal/appsignal-ruby [cli-install]: /ruby/command-line/install.html [cli-diagnose]: /ruby/command-line/diagnose.html [cli-demo]: /ruby/command-line/demo.html # AppSignal for Ruby: Demo tool Source: https://docs.appsignal.com/ruby/command-line/demo <VersionRequirements /> The AppSignal gem includes a command-line tool that sends demonstration samples to AppSignal. When the tool is run, it sends an error and performance sample from your machine to AppSignal. This command-line tool is useful for testing AppSignal on a system and validating your local configuration. The same test is also run during installation when using the [`appsignal install` command](/ruby/command-line/install). To learn more about how to use the demonstration command, visit the [Debugging page][debugging]. ## Usage To run the demonstration tool, run the following terminal command from your project's root folder: <CodeGroup> ```bash Bash theme={null} appsignal demo ``` </CodeGroup> If you want to make sure the config for a specific environment is used, you can use the optional [`--environment`](#environment-option): <CodeGroup> ```bash Bash theme={null} appsignal demo --environment=production ``` </CodeGroup> ## Available Options | Option | Usage | Description | | ----------- | ---------------------------------- | -------------------------------------------------------------------------- | | environment | `--environment=<environment_name>` | Set the environment to use in the command, e.g. `production` or `staging`. | [debugging]: /support/debugging.html # AppSignal for Ruby: Diagnose tool Source: https://docs.appsignal.com/ruby/command-line/diagnose <VersionRequirements /> The AppSignal Ruby gem includes a self-diagnostic tool that can be used to debug the installation and configuration of your AppSignal integration. It is one of the first tools that our support team requests you to run when debugging an issue. ## The diagnostic report You can use this diagnostic tool to test and validate your AppSignal installation. It outputs useful information to debug issues and it checks if AppSignal agent is able to run on the machine's architecture and communicate with the AppSignal servers. This diagnostic tool collects and outputs the following: * Information about the AppSignal gem. * Information about the host system and Ruby. * If the AppSignal [extension](/appsignal/how-appsignal-operates#extension) and [agent](/appsignal/how-appsignal-operates#agent) can run on the host system. * All configured config options (including default values). * If the configuration is valid and active. * If the Push API key is present and valid (internet connection required). * Where configuration option values originate from. * If the required system paths exist, are writable, and which user and group are owners. * Small parts of the tail from the available log files. You can read more about how to use the diagnose command in our [Debugging](/support/debugging) documentation. ## Submitting the report In gem version `2.2.0` and higher you will be prompted to send the report to AppSignal. If accepted the report will be send to our servers and you will receive a support token. When you [send this support token to us](mailto:support@appsignal.com) we will review the report and help you debug the issue. We've seen that copy-pasting the report output usually loses formatting and makes it harder to read, which is why it's send to our servers in the JSON format. In gem version `2.8.0` the option was added to view the report yourself on AppSignal.com. A link to the report is printed in the diagnose output. This web view will also show any validation problems and warnings our system detected. ## Usage On the command-line in your project run: <CodeGroup> ```bash Bash theme={null} appsignal diagnose ``` </CodeGroup> If you're experiencing an issue in production and need to send the report to AppSignal for support, you can run the following command to generate and send the report to our servers: <CodeGroup> ```bash Bash theme={null} bundle exec appsignal diagnose --environment=production --send-report ``` </CodeGroup> ## Options | Option | Description | | ---------------------------------------------------- | -------------------------------------------------------------------------- | | [`--environment=<environment>`](#environment-option) | Set the environment to use in the command, e.g. `production` or `staging`. | | [`--[no-]send-report`](#report-submission-option) | Automatically send, or do not send the report. | | `--[no-]color` | Toggle the colorization of the output. | ### Environment option To select a specific environment with the CLI, run the below command: <CodeGroup> ```bash Bash theme={null} appsignal diagnose --environment=production ``` </CodeGroup> The environment option is useful when there is no default environment (non-Rails apps and apps configured with an [config file](/ruby/configuration/load-order#file)) or the default environment is not the one you want to diagnose. The diagnose tool will warn you when no environment is selected. ### Report submission option The options to [submit the report](#submitting-the-report) immediately, or not, were added to the AppSignal gem version `2.8.0`. Selecting whether or not to send the report with these options will no longer prompt this question, making it easier to use in non-interactive environments. To run diagnose and submit the report data to AppSignal, run the below command: <CodeGroup> ```bash Bash theme={null} appsignal diagnose --send-report ``` </CodeGroup> To run diagnose without sending the report data to AppSignal, run the below command: <CodeGroup> ```bash Bash theme={null} appsignal diagnose --no-send-report ``` </CodeGroup> ## Configuration output format ### Configuration option values format The configuration options are printed to the CLI as their inspected values. This means we print them as Ruby would in a console. * Strings values are printed with double quotes around them, e.g. `"My app name"`. * Booleans values are printed as their raw values: `true` and `false`. * Arrays values are printed as a collection of values surrounded by square brackets, e.g. `["HTTP_ACCEPT", "HTTP_ACCEPT_CHARSET"]`. * Empty Arrays are printed as two square brackets: `[]`. * Nil values are printed as `nil`. ### Configuration sources The configuration section also displays the origin of config option values, which can help identify sources that override values defined in other config sources. You can read more about configuration sources their load order, and priority in the [configuration load order](/ruby/configuration/load-order) documentation. The configuration options are displayed based on the source of their values and the number of sources that set them, like in the below example: ```text Shell theme={null} Configuration # Option with a value loaded only from the default source send_params: true # Option with one source # A different source than the default source name: "My app name" (Loaded from file) # Option with multiple sources # Listed in order of priority (highest priority last) active: true Sources: default: false file: false env: true ``` [debugging]: /support/debugging.html # AppSignal for Ruby: Install Source: https://docs.appsignal.com/ruby/command-line/install Command-line tool to install AppSignal in a Ruby application. Documentation on usage, options and configuration methods. The documentation tells you everything you need to know about installing AppSignal via the command-line tool. ## Description The command-line tool helps with setting up the configuration for your application. Integration with Ruby applications not using the Rails framework requires additional steps, because the AppSignal installer does not know how your application is set up. We recommend you our [installation guide](/guides/new-application) when adding a new application to AppSignal. For Rails applications, full integration is automatic. For other frameworks, please refer to our [Integrations documentation](/ruby/integrations/). Once the installation is complete, run the [demo tool command](/ruby/command-line/demo) to verify that the installation was successful. The demo tool command sends sample data from your application to the AppSignal servers, which helps you verify that everything is working properly. ## Configuration methods There are two configuration methods provided by the command-line installer: 1. [Configuration via a configuration file](#1-configuration-file) 2. [Configuration via environment variables](#2-environment-variables). ### 1. Configuration file AppSignal can be configured via a configuration file called `appsignal.rb` or `appsignal.yml`, located in your application in the `config/` directory. When choosing this option our installer will write your configuration to this file. When configuring your AppSignal integration via the configuration file, the Push API key you provide to the installer will be written into the `appsignal.yml` configuration file. We do not recommend adding this key to version control systems such as Git, SVN or Mercurial. Instead, use the `APPSIGNAL_PUSH_API_KEY` environment variable to store your API key. You can read more about configuring your application in our [configuration documentation](/ruby/configuration). ### 2. Environment variables AppSignal can be configured through system environment variables. If you select this option, no [configuration file](#1-configuration-file) will be generated. You can read more about configuring your application in our [configuration documentation](/ruby/configuration). ## Usage To install appsignal via the command-line, navigate to your project directory and run the following command: <CodeGroup> ```bash Bash theme={null} appsignal install <Push API key> # For example appsignal install 1234-1234-1234-1234 ``` </CodeGroup> Your application's "Push API key" will be displayed in the [installation wizard](https://appsignal.com/redirect-to/organization?to=sites/new) and is also available in the administration section of your organization's settings, or via [this link](https://appsignal.com/redirect-to/organization?to=admin/api_keys). ## Available Options | Option | Usage | Description | | ------ | -------------- | -------------------------------------- | | color | `--[no-]color` | Toggle the colorization of the output. | # AppSignal Ruby configuration Source: https://docs.appsignal.com/ruby/configuration Configuration. Important, because without it the AppSignal Ruby gem won't know which application it's instrumenting or in which environment. In this topic we'll explain how to configure AppSignal, what can be configured in the Ruby gem, what's the minimal configuration needed and how the configuration is loaded. ## Minimal required configuration For applications to report data to AppSignal the following configuration is required. All other configuration is optional. * Application name - [name option](/ruby/configuration/options#option-name) * Application environment - [environment](/ruby/configuration/options#option-appsignal_app_env) (automatically detected or set with an environment variable) * Application push API key - [push\_api\_key option](/ruby/configuration/options#option-push_api_key) * AppSignal to be active - [active option](/ruby/configuration/options#option-active) For Rails apps you do not have to configure your application name, AppSignal will use the name of your application by default. If you use a framework that is aware of environments and [is supported by the AppSignal gem](/ruby/integrations), the environment is detected automatically. <CodeGroup> ```ruby Ruby theme={null} # config/appsignal.rb Appsignal.configure do |config| config.activate_if_environment(:development, :staging, :production) config.name = "My app" config.push_api_key = "1234-1234-1234" end ``` ```bash Bash theme={null} # Environment variables export APPSIGNAL_APP_NAME="My app" export APPSIGNAL_APP_ENV="production" export APPSIGNAL_PUSH_API_KEY="1234-1234-1234" ``` ```yaml YAML theme={null} # config/appsignal.yml # Legacy config method production: active: true name: "My app" push_api_key: "1234-1234-1234" ``` </CodeGroup> ## Configuration methods There are several different configuration methods available in our Ruby gem. To see in which order they're loaded and which configuration method overrides values from other sources, see our [configuration load order](/ruby/configuration/load-order) page. ### Ruby configuration file <Compatibility /> The AppSignal Ruby gem can be configured using a Ruby configuration file. When selected, the installer automatically creates a `config/appsignal.rb` file. This file includes default configuration settings that can be customized to meet your application's specific needs. This configuration file is read when `Appsignal.start` is called, which is called automatically for most of our [integrations](/ruby/integrations). Please read the [integrating AppSignal instructions](/ruby/instrumentation/integrating-appsignal) if `Appsignal.start` is not automatically called. The configuration file configures our Ruby gem using [the `Appsignal.configure` helper](#appsignalconfigure-helper). Please read the [the `Appsignal.configure` helper](#appsignalconfigure-helper) section for more details on how to use it. The [YAML configuration file](#yaml-configuration-file) will not be read when this file is present. <CodeGroup> ```ruby Ruby theme={null} Appsignal.configure do |config| # Enable AppSignal for the following environments config.activate_if_environment(:development, :staging, :production) # Ignore this action for all environments config.ignore_actions << "My global action" # Ignore this action for only the production environment if config.env?(:production) config.ignore_actions << "My production action" end # Ignore this action for only the staging environment if config.env?(:staging) config.ignore_actions << "My staging action" end end ``` </CodeGroup> ### `Appsignal.configure` helper The `Appsignal.configure` helper can be used to configure AppSignal using Ruby code. The [Ruby configuration file](#ruby-configuration-file) uses this helper and it can also be used directly in your application. If your app uses `Appsignal.configure` outside the `config/appsignal.rb` file, like a Rails initializer, please read [this section on the differences in behavior](#using-the-appsignalconfigure-helper-in-your-application) this has. Set configuration options inside the `Appsignal.configure` block by calling the writer methods on the `config` object. [Configuration options](/ruby/configuration/options) can be set using the "Config file key" listed for the configuration options. For example, the [`send_params` option](/ruby/configuration/options#option-send_params) can be set using: `config.send_params = false`. <CodeGroup> ```ruby Ruby theme={null} # Some examples on how to configure config options Appsignal.configure do |config| # Enable AppSignal for the following environments config.activate_if_environment(:development, :staging, :production) # Configure String config options config.name = "My app name" # Read a value from an environment variable config.hostname = ENV.fetch("HOSTNAME", "default hostname value") # Append values to Array config options config.ignore_actions += ["My ignored action", "My other ignored action"] config.request_headers << "MY_HTTP_HEADER" # Configure Boolean config options config.send_params = true config.enable_host_metrics = false end ``` </CodeGroup> Read the rest of this section for more details on how the `Appsignal.configure` helper works and what other helpers it has. #### String config options Configuration options of the type String can be set using both Strings and Symbols. When set, we will convert Symbols to Strings. <CodeGroup> ```ruby Ruby theme={null} Appsignal.configure do |config| config.activejob_report_errors = :discard config.activejob_report_errors # => "discard" end ``` </CodeGroup> #### Array config options Configuration options of the type Array can be modified as a normal array: * Use an assignment to override defaults and previously read values from environment variables. * For example: `config.array_option = ["value 1", "value 2"]` * Option value: `["value 1", "value 2"]` * Use the *addition assignment operator* `+=` to merge a new array of values with the defaults and previously read values from environment variables. * For example: `config.array_option += ["value 1", "value 2"]` * Option value: `["DUMMY default value", "value 1", "value 2"]` * Use the *append operator* `<<` to append a single value to the list of the defaults and previously read values from environment variables. * For example: `config.array_option << "value 1"` * Option value: `["DUMMY default value", "value 1"]` #### Automatic environment detection The AppSignal Ruby gem detects the application's environment automatically. We integrate with gems like Rails, Sinatra, Rack, and others to detect which environment the application has started in. For this reason, it should not be necessary to configure the environment manually. If you need to configure the application environment manually, pass the environment name as the first argument to the `Appsignal.configure` helper. This argument will override the [`APPSIGNAL_APP_ENV` environment variable value](/ruby/configuration/options#option-appsignal_app_env) and the automatic environment detection. <CodeGroup> ```ruby Ruby theme={null} # Configure the application environment explicitly to be "production" Appsignal.configure(:production) do |config| # Some config end ``` </CodeGroup> #### `activate_if_environment` helper The `Appsignal.configure` helper has a helper to configure which environments should be active and report data to AppSignal.com. Call the `activate_if_environment` with a list of environments (Strings and/or Symbols). AppSignal detects the environment when the `Appsignal.configure` helper is called without an environment argument. It will then check if the environment matches any of the given values, and if so, set the [active config option](/ruby/configuration/options#option-active) to `true`. <CodeGroup> ```ruby Ruby theme={null} Appsignal.configure do |config| # Enable AppSignal for the following environments config.activate_if_environment(:development, :staging, :production) end ``` </CodeGroup> The `activate_if_environment` helper is a convenience helper to prevent applications from having to add their own checks on when AppSignal should be active, like: <CodeGroup> ```ruby Ruby theme={null} Appsignal.configure do |config| # Example of a manual check for which environments AppSignal should be active config.active = Rails.env.development? || Rails.env.staging? || Rails.env.production? end ``` </CodeGroup> #### `env?` helper The `Appsignal.configure` helper has a helper to check which environment AppSignal has detected. Use this helper to check which environment is active to set the configuration options that should only apply to this environment. Call the `env?` helper with an environment name (String or Symbol), and it will return `true` if the environment name matches the currently active environment. <CodeGroup> ```ruby Ruby theme={null} Appsignal.configure do |config| # Add this configuration only for the staging environment if config.env?(:staging) config.ignore_actions << "My staging action" end end ``` </CodeGroup> #### Using the `Appsignal.configure` helper in your application We recommend configuring the AppSignal Ruby gem using the [Ruby configuration file](#ruby-configuration-file) at `config/appsignal.rb`. If a Rails initializer or inline configuration is preferred, please read this section for the changes in behavior this has. If the `Appsignal.configure` helper is called before the `config/appsignal.rb` Ruby config file is read when `Appsignal.start` is called, it will not read the Ruby configuration file. In Rails apps, make sure to [configure the AppSignal gem to start after Rails is initialized](/ruby/integrations/rails#configure-appsignal-in-an-initializer), otherwise the config set with `Appsignal.configure` is ignored when called in a Rails initializer like `config/initializers/appsignal.rb`. <Warning> In Ruby gem version 3.12 and newer, if a [YAML configuration file](#yaml-configuration-file) is present, it will be read when `Appsignal.configure` is called in a Rails initializer or inline in an application. This is deprecated behavior. Please move all configuration to the `Appsignal.configure` helper. We will remove this behavior in the next major version of the Ruby gem. </Warning> Example Rails initializer: <CodeGroup> ```ruby Ruby theme={null} # Example file: config/initializers/appsignal.rb # WARNING: In this example the `config/appsignal.rb` config file is not read! Appsignal.configure do |config| # Set some config end ``` </CodeGroup> Example inline configuration: <CodeGroup> ```ruby Ruby theme={null} # Example file: app.rb require "appsignal" require "web_framework" # WARNING: In this example the `config/appsignal.rb` config file is not read! Appsignal.configure do |config| # Set some config end Appsignal.start run WebFramework.app ``` </CodeGroup> ### System environment variables AppSignal can also be configured using system environment variables on the host the application AppSignal is monitoring. This is common on platforms such as Heroku. Make sure these environment variables are configured in the way that's compatible with your Operating System and that the values get loaded before your app with AppSignal is started. <CodeGroup> ```sh Shell theme={null} export APPSIGNAL_APP_NAME="My app" ``` </CodeGroup> ### YAML configuration file <Tip> This configuration method is a legacy method and will be removed in the next major version of the Ruby gem. Please use the [Ruby configuration file](#ruby-configuration-file) instead. </Tip> The AppSignal Ruby gem can be configured with a YAML configuration file. During installation the Ruby gem will create a `config/appsignal.yml` file, if selected. In this file some default configuration is supplied and can be modified to fit your application's needs. This `config/appsignal.yml` file supports ERB tags so that system environment variables can also be loaded in this file. The `config/appsignal.yml` configuration examples shown for configuration options will use the `default` YAML anchor. The AppSignal installer will create an `config/appsignal.yml` file with this anchor by default. If not present, make sure you add the config option to the correct environment. <CodeGroup> ```yaml YAML theme={null} # config/appsignal.yml # Define the "defaults" anchor default: &defaults name: "My app" # Supports ERB push_api_key: "<%= ENV['APPSIGNAL_PUSH_API_KEY'] %>" production: # Loads the defaults in the production environment by referencing the anchor <<: *defaults # production environment specific configuration active: true ``` </CodeGroup> #### Multiple app environments Multiple app environments can be configured in this file using root-level keys. <CodeGroup> ```yaml YAML theme={null} # Example: config/appsignal.yml development: # Development app environment active: true production: # Production app environment active: true test: # Testing app environment active: false # Disabled for test environment ``` </CodeGroup> To avoid having to repeat the configuration for every app environment, we can use YAML anchors to extend YAML objects. <CodeGroup> ```yaml YAML theme={null} # Example: config/appsignal.yml default: &defaults active: true development: # Development app environment <<: *defaults production: # Production app environment <<: *defaults test: # Testing app environment <<: *defaults active: false # Overwrites the inherited active config option from "defaults" ``` </CodeGroup> It's not possible to only configure a `defaults` anchor and have it apply to all environments automatically. Every environment needs to be configured in the YAML file with a root-level key and extend from this `defaults` anchor. #### Example YAML configuration file Here's an example of an `appsignal.yml` configuration file. It's recommended you only add the configuration you need to your configuration file. For the full list of options, please see the [configuration options](/ruby/configuration/options) page. <CodeGroup> ```yaml YAML theme={null} # config/appsignal.yml default: &defaults # Your Push API Key, it is possible to set this dynamically using ERB. Required push_api_key: "<%= ENV['APPSIGNAL_PUSH_API_KEY'] %>" # Your app's name as reported on AppSignal.com. Required name: "My App" # Your server's hostname. Optional, auto detected hostname: "frontend1.myapp.com" # Add default instrumentation of net/http. Default: true instrument_net_http: true # Skip session data, if it contains private information. Default: false skip_session_data: true # Ignore these errors (Optional) ignore_errors: - SystemExit # Ignore these actions, used by our Loadbalancer. Optional ignore_actions: - IsUpController#index # Enable allocation tracking for memory metrics. Default: true enable_allocation_tracking: true # Configuration per environment, leave out an environment or set active # to false to not push metrics for that environment. development: <<: *defaults active: true # Set the severity level of AppSignal's internal logger. Optional # Supported values are error, warning, info, debug, trace log_level: debug staging: <<: *defaults # Configure AppSignal to be active for this environment. Required active: true production: <<: *defaults # Configure AppSignal to be active for this environment. Required active: true # Set different path for the log file. Optional, auto detected log_path: "/home/my_app/app/shared/log" # Set AppSignal working dir. Optional, auto detected working_directory_path: "/tmp/appsignal" # When it's not possible to connect to the outside world without a proxy. # Optional http_proxy: "proxy.mydomain.com:8080" ``` </CodeGroup> # AppSignal for Ruby load order Source: https://docs.appsignal.com/ruby/configuration/load-order The AppSignal Ruby gem can be configured in a couple different ways. Through an initializer, with a configuration file or through environment variables. <Warning> In Ruby gem version 2.0 the load order changed! Step 4 and 5 were swapped, making sure that environment variables are loaded after the `appsignal.yml` configuration file. Read more about it in the [Pull Request on GitHub](https://github.com/appsignal/appsignal-ruby/pull/180). </Warning> The configuration is loaded in a five step process. Starting with the gem defaults and ending with reading environment variables. The configuration options can be mixed without losing configuration from a different option. Using an initializer, a configuration file and environment variables together will work. ## Config sources * 1. [Gem defaults - `default`](#1-gem-defaults) * 2. [System detected settings - `system`](#2-system-detected-settings) * 3. [Initial configuration - `initial`](#3-initial-configuration-given-to-config-initializer) * 4. [`appsignal.yml` config file - `file`](#4-appsignalyml-config-file) * 5. [Environment variables - `env`](#5-environment-variables) * 6. [`appsignal.rb` config file - `dsl`](#appsignal-rb-config-file) * 7. [`Appsignal.configure` - `dsl`](#appsignal-configure-helper) ## 1. Gem defaults The AppSignal gem starts with loading its default configuration, setting paths and enabling certain features. The agent defaults can be found in the [gem source](https://github.com/appsignal/appsignal-ruby/blob/main/lib/appsignal/config.rb) as `Appsignal::Config::DEFAULT_CONFIG`. This source is listed as `default` in the [diagnose](/ruby/command-line/diagnose) output. ## 2. System detected settings The gem detects what kind of system it's running on and configures itself accordingly. For example, when it's running inside a container based system (such as Docker and Heroku) it sets the configuration option `:running_in_container` to `true`. This source is listed as `system` in the [diagnose](/ruby/command-line/diagnose) output. ## 3. Initial configuration given to `Config` initializer <Warning> This configuration method has been deprecated since Ruby gem 3.12 and removed in Ruby gem 4.0.0 in favor of [`Appsignal.configure`](#appsignal-configure-helper). </Warning> When manually creating a `Appsignal::Config` class you can pass in the initial configuration you want to apply. This is a hash of any of the options described below. <CodeGroup> ```ruby Ruby theme={null} Appsignal.config = Appsignal::Config.new(Dir.pwd, "production", { active: true, name: "My app!", push_api_key: "e55f8e96-62df-4817-b672-d10c8d924065" }) ``` </CodeGroup> This step will override all given options from the defaults or system detected configuration. This source is listed as `initial` in the [diagnose](/ruby/command-line/diagnose) output. ## 4. `appsignal.yml` config file <Warning> This configuration method will be removed in the next major version of the Ruby gem. We recommend using the [`appsignal.rb` config file](#6-appsignal-dsl) instead. </Warning> A way to configure your application is using the `appsignal.yml` file. When you use the `appsignal install` command the gem will create one for you. The path of this configuration file is `{project_root}/config/appsignal.yml`. This step will override all given options from the defaults, system detected and initializer configuration. Read [the `appsignal.yml` config file](/ruby/configuration#yaml-configuration-file) documentation for more information on how this configuration method works. This source is listed as `file` in the [diagnose](/ruby/command-line/diagnose) output. <a /> ## 5. Environment variables AppSignal will look for its configuration in environment variables. When found these will override all given configuration options from previous steps. <CodeGroup> ```bash Bash theme={null} export APPSIGNAL_APP_NAME="my custom app name" # start your app here ``` </CodeGroup> Read [the system environment variables](/ruby/configuration#system-environment-variables) documentation for more information on how this configuration method works. This source is listed as `env` in the [diagnose](/ruby/command-line/diagnose) output. ## 6. `appsignal.rb` config file A way to configure your application is using the `appsignal.rb` file. The path of this configuration file is `{project_root}/config/appsignal.rb`. This load path cannot be customized. This step will override all given options from the defaults, system detected and environment variables. If both an [`appsignal.yml` config file](#4-appsignalyml-config-file) and a `appsignal.rb` config file are present, only the `appsignal.rb` config file is loaded. Read [the `appsignal.rb` config file](/ruby/configuration#ruby-configuration-file) documentation for more information on how this configuration method works. This source is listed as `dsl` in the [diagnose](/ruby/command-line/diagnose) output. ## 7. Appsignal.configure helper <Warning> In version 3 and 4 of the Ruby gem, calling the `Appsignal.configure` helper will also load the `appsignal.yml` file, if present. This behavior will *removed* in the next major version of the Ruby gem. Please only use the [`appsignal.rb` config file](#appsignal-rb-config-file) or [`Appsignal.configure` helper](#configure-helper). </Warning> Lastly, the Ruby gem can be configured using the `Appsignal.configure` helper in the application. When called, any config options configured using this helper will overwrite all given configuration options from previous sources. If a `config/appsignal.rb` config file is also present in the project, it will **not be loaded** if the `Appsignal.configure` helper is called first in your application. Read [the `Appsignal.configure` helper](/ruby/configuration#appsignalconfigure-helper) documentation for more information on how this configuration method works. This source is listed as `dsl` in the [diagnose](/ruby/command-line/diagnose) output. # Ruby gem configuration options Source: https://docs.appsignal.com/ruby/configuration/options The following list includes all configuration options with the name of the environment variable and the name of the key in the configuration file. For more information on how to configure AppSignal with a configuration file or system environment variables, see our [Configuration](/ruby/configuration) topic. ## Available options * Required options * [`active`](#option-active) * [`APPSIGNAL_APP_ENV`](#option-appsignal_app_env) * [`name`](#option-name) * [`push_api_key`](#option-push_api_key) * Options * [`activejob_report_errors`](#option-activejob_report_errors) * [`bind_address`](#option-bind_address) * [`ca_file_path`](#option-ca_file_path) * [`cpu_count`](#option-cpu_count) * [`debug`](#option-debug) * [`default_tags`](#option-default_tags) * [`dns_servers`](#option-dns_servers) * [`enable_active_support_event_log_reporter`](#option-enable_active_support_event_log_reporter) * [`enable_allocation_tracking`](#option-enable_allocation_tracking) * [`enable_at_exit_hook`](#option-enable_at_exit_hook) * [`enable_at_exit_reporter`](#option-enable_at_exit_reporter) * [`enable_frontend_error_catching`](#option-enable_frontend_error_catching) * [`enable_gvl_global_timer`](#option-enable_gvl_global_timer) * [`enable_gvl_waiting_threads`](#option-enable_gvl_waiting_threads) * [`enable_host_metrics`](#option-enable_host_metrics) * [`enable_minutely_probes`](#option-enable_minutely_probes) * [`enable_nginx_metrics`](#option-enable_nginx_metrics) * [`enable_rails_error_reporter`](#option-enable_rails_error_reporter) * [`enable_rake_performance_instrumentation`](#option-enable_rake_performance_instrumentation) * [`enable_statsd`](#option-enable_statsd) * [`endpoint`](#option-endpoint) * [`files_world_accessible`](#option-files_world_accessible) * [`filter_metadata`](#option-filter_metadata) * [`filter_parameters`](#option-filter_parameters) * [`filter_session_data`](#option-filter_session_data) * [`host_role`](#option-host_role) * [`hostname`](#option-hostname) * [`http_proxy`](#option-http_proxy) * [`ignore_actions`](#option-ignore_actions) * [`ignore_errors`](#option-ignore_errors) * [`ignore_logs`](#option-ignore_logs) * [`ignore_namespaces`](#option-ignore_namespaces) * [`instrument_code_ownership`](#option-instrument_code_ownership) * [`instrument_http_rb`](#option-instrument_http_rb) * [`instrument_net_http`](#option-instrument_net_http) * [`instrument_ownership`](#option-instrument_ownership) * [`instrument_redis`](#option-instrument_redis) * [`instrument_sequel`](#option-instrument_sequel) * [`log`](#option-log) * [`log_level`](#option-log_level) * [`log_path`](#option-log_path) * [`nginx_port`](#option-nginx_port) * [`ownership_set_namespace`](#option-ownership_set_namespace) * [`request_headers`](#option-request_headers) * [`revision`](#option-revision) * [`running_in_container`](#option-running_in_container) * [`send_environment_metadata`](#option-send_environment_metadata) * [`send_params`](#option-send_params) * [`send_session_data`](#option-send_session_data) * [`sidekiq_report_errors`](#option-sidekiq_report_errors) * [`skip_session_data`](#option-skip_session_data) * [`statsd_port`](#option-statsd_port) * [`transaction_debug_mode`](#option-transaction_debug_mode) * [`working_dir_path`](#option-working_dir_path) * [`working_directory_path`](#option-working_directory_path) ## active <a /> | Field | Value | | ----------------------- | ------------------------------------------------------------------------------ | | Config file key | `active` | | System environment key | `APPSIGNAL_ACTIVE` | | Required | yes | | Type | Boolean (`true` / `false`) | | Default value | `false` / detected by system | | Available since version | `0.3.0` | | | <ul><li>`0.11.6`: Support added for the environment variable option.</li></ul> | ### Description <Note> **Note**: When the [`APPSIGNAL_PUSH_API_KEY`](#option-push_api_key) environment variable is set, this defaults to `true`. This can be overridden by setting the `APPSIGNAL_ACTIVE` system environment variable to `false`: `APPSIGNAL_ACTIVE=false`. </Note> Configure AppSignal to be active or not for a given environment. Most commonly used in the [file configuration](/ruby/configuration) per environment. ## APPSIGNAL\_APP\_ENV <a /> | Field | Value | | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | System environment key | `APPSIGNAL_APP_ENV` | | Required | yes | | Type | `String` | | Default value | `""` / detected by system | | Available since version | `0.11.8` | | | <ul><li>`1.3.0`: Support added for Padrino.</li><li>`1.3.6`: Support added for Sinatra.</li><li>`2.0.4`: Standardizes the behavior for all configuration.</li></ul> | ### Description The environment of the app to be reported to AppSignal. This config option will be automatically detected in Rails apps. For Rails apps the `RAILS_ENV` variable is used to detect the environment. For apps using other frameworks or none at all, the `RACK_ENV` environment variable is used. To override this automatic detection, set the `APPSIGNAL_APP_ENV` environment variable. ```sh Shell theme={null} export APPSIGNAL_APP_ENV=staging rackup ``` This option will be used to load the configuration from the [config files](/ruby/configuration) in which the AppSignal configuration is stored. The environment variable option is commonly used on platforms where apps run in the `production` environment by default, such as Heroku. This setting allows an override to set the environment to `staging`, for example. ```sh Shell theme={null} heroku config:set APPSIGNAL_APP_ENV=staging ``` If the environment is set using the [`Appsignal.configure` helper](/ruby/configuration/load-order#configure-helper), it will override the `APPSIGNAL_APP_ENV` environment variable. <Note> **Note**: Changing the [name](#option-name) or environment of an existing app will create a new app on AppSignal.com. </Note> <Note> **Note**: This config option has no config file key equivalent. To set the environment on AppSignal initialization, you'll need to [initialize the configuration manually](/ruby/instrumentation/integrating-appsignal#configuration-file). </Note> <h4> Custom environments in config file </h4> There is no `env` key available in the `config/appsignal.yml` file. If you wish to dynamically set the environment name for an app in the config file it's possible to customize your config file to use the environment to create an environment. ```yaml YAML theme={null} # config/appsignal.yml <%= ENV["APPSIGNAL_APP_ENV"] %>: active: true ``` If you use another environment variable than `APPSIGNAL_APP_ENV` make sure that matches the value is any of the auto detected environment variable names (`RAILS_ENV` and `RACK_ENV`) or the value given to [`Appsignal.configure`](/ruby/configuration#ruby-configuration-file). <Note> **Note**: Changing the [name](#option-name) or environment of an existing app will create a new app on AppSignal.com. </Note> ## name <a /> | Field | Value | | ----------------------- | ------------------------------ | | Config file key | `name` | | System environment key | `APPSIGNAL_APP_NAME` | | Required | yes | | Type | `String` | | Default value | nil (This is unset by default) | | Available since version | `1.0.0` | ### Description Name of your application as it should be displayed on AppSignal.com. If you use Ruby on Rails the gem will auto-detect the name and you can leave this empty. For other frameworks setting this is mandatory. <Note> **Note**: Changing the name or [environment](#option-env) of an existing app will create a new app on AppSignal.com. </Note> ## push\_api\_key <a /> | Field | Value | | ----------------------- | ------------------------------ | | Config file key | `push_api_key` | | System environment key | `APPSIGNAL_PUSH_API_KEY` | | Required | yes | | Type | `String` | | Default value | nil (This is unset by default) | | Available since version | `0.1.0` | ### Description The organization-level authentication key to authenticate with our Push API. Read more about the [AppSignal Push API key](/appsignal/terminology#push-api-key). <Note> **Note**: When the [`APPSIGNAL_PUSH_API_KEY`](#option-push_api_key) system environment variable is set, the [`active`](#option-active) option will default to `true` instead of `false`. This means AppSignal will be consider active for the loaded environment even if `active` is set to `false` in the config file. For more information see the [`active`](#option-active) option. </Note> ## activejob\_report\_errors <a /> | Field | Value | | ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Config file key | `activejob_report_errors` | | System environment key | `APPSIGNAL_ACTIVEJOB_REPORT_ERRORS` | | Required | no | | Type | `String` | | Default value | `all` | | Available since version | `3.6.1` | | | <ul><li>The `discard` value was added in Ruby gem 3.7.3.</li><li>The `APPSIGNAL_ACTIVEJOB_REPORT_ERRORS` environment variable was added in Ruby gem 3.9.0.</li></ul> | ### Description Configure the reporting of errors that occur in [Active Job](/ruby/integrations/active-job) jobs. This option allows the disabling of error reporting for Active Job jobs, to allow for custom error reporting to be added. Accepted values: * `all`: Report all errors for every execution of jobs, including retries. * `discard`: Report errors when the job is discarded due to the error. Use this option to only report errors when all job retries have been exhausted. * `none`: Report no errors for jobs, including retries. <Note> **Note**: The `discard` option only works on Active Job 7.1 and newer. On lower versions `discard` is read as `all`. </Note> ## bind\_address <a /> | Field | Value | | ----------------------- | ------------------------ | | Config file key | `bind_address` | | System environment key | `APPSIGNAL_BIND_ADDRESS` | | Required | no | | Type | `String` | | Default value | `127.0.0.1` | | Available since version | `3.4.8` | ### Description A valid IPv4 address the AppSignal agent uses as a binding for its TCP and UDP servers. Use a specific address if you only want the agent to listen to requests made to that address. Set this option to `0.0.0.0` to allow to receive requests from hosts using any IP address. By default it only listens to requests made on the same host. This option is applied to all the agent servers ([StatsD](#option-enable_statsd), [OpenTelemetry](#option-enable_opentelemetry_http) and [NGINX](#option-enable_nginx_metrics)). ## ca\_file\_path <a /> | Field | Value | | ----------------------- | -------------------------------- | | Config file key | `ca_file_path` | | System environment key | `APPSIGNAL_CA_FILE_PATH` | | Required | no | | Type | `String` | | Default value | Packaged `cacert.pem` file path. | | Available since version | `1.3.5` | ### Description Configure the path of the SSL certificate file. By default this points to the AppSignal [vendored `cacert.pem` file](https://github.com/appsignal/appsignal-ruby/blob/4eed259e122d10df66655098ad0aa8a362f3297d/resources/cacert.pem) in the gem itself. Use this option to point to another certificate file if there's a problem connecting to our API. <Note> **Note**: The specified path cannot contain Operating Specific file system abstractions, such as the homedir symbol `~` for \*NIX systems. This will be seen as a malformed path. </Note> ## cpu\_count <a /> | Field | Value | | ----------------------- | --------------------- | | Config file key | `cpu_count` | | System environment key | `APPSIGNAL_CPU_COUNT` | | Required | no | | Type | `Float` | | Default value | `undefined` | | Available since version | `3.6.3` | ### Description The available CPU capacity of the host, in number of CPUs. This is used to calculate the CPU usage percentage in the host metrics. If not set, the agent will attempt to automatically detect this from cgroups. The number of CPUs can be a fraction, e.g. `0.5`. ## debug <a /> | Field | Value | | ----------------------- | ----------------------------------------------------------------------------------------------------------------- | | Config file key | `debug` | | System environment key | `APPSIGNAL_DEBUG` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `false` | | Available since version | `1.0.0` | | | <ul><li>Deprecated since version 3.0.16 in favor of the [`log_level` config option](#option-log_level).</li></ul> | ### Description <Warning> **Warning**: This config option is deprecated in Ruby gem 3.0.16. Please use the [`log_level`](#option-log_level) option instead for Ruby gem 3.0.16 and newer. </Warning> Enable debug logging, this is usually only needed on request from support. With this option enabled AppSignal will log a lot more information about decisions that are made during metrics collection and when data is sent to AppSignal.com servers. Enabling debug logging could have a slight impact on the disk usage and IO, especially on high-traffic sites. CPU overhead is minimal with the debug option enabled. <Note> This option sets the severity level of AppSignal's internal logger. This configuration option does not affect the [logging feature](/logging). </Note> ## default\_tags <a /> | Field | Value | | ----------------------- | -------------------------------------------------------- | | Config file key | `default_tags` | | System environment key | `APPSIGNAL_DEFAULT_TAGS` | | Required | no | | Type | `Hash[String, (String \| Symbol \| Integer \| Boolean)]` | | Default value | undefined | | Available since version | `4.8.3` | ### Description Default tags that will be added to all transactions. Transaction-specific tags set with [`Appsignal.add_tags`](/guides/tagging#ruby) will override default tags with the same key. <CodeGroup> ```ruby title="config/appsignal.rb" theme={null} Appsignal.configure do |config| config.default_tags = { "region" => "europe", "shard" => "shard-1" } end ``` ```yaml title="config/appsignal.yml" theme={null} default: &defaults default_tags: region: europe shard: shard-1 ``` </CodeGroup> When using the environment variable, provide a comma-separated list of key-value pairs. ```bash Shell theme={null} export APPSIGNAL_DEFAULT_TAGS="region=europe,shard=shard-1" ``` Tag values must be a String, Symbol, Integer, or Boolean. Tags with other value types will be ignored. Read more about [tagging](/guides/tagging). ## dns\_servers <a /> | Field | Value | | ----------------------- | ---------------------------------------------------------------------------- | | Config file key | `dns_servers` | | System environment key | `APPSIGNAL_DNS_SERVERS` | | Required | no | | Type | `Array<String>` | | Default value | `[]` | | Available since version | `2.2.0.beta.1` | | | <ul><li>`2.11.0`: Support added for the system environment option.</li></ul> | ### Description Configure DNS servers for the AppSignal agent to use. <CodeGroup> ```ruby title="config/appsignal.rb" theme={null} Appsignal.configure do |config| config.dns_servers = ["8.8.8.8", "8.8.4.4"] end ``` ```yaml title="config/appsignal.yml" theme={null} default: &defaults dns_servers: - 8.8.8.8 - 8.8.4.4 ``` ```sh title="Environment variables" theme={null} # In the host environment export APPSIGNAL_DNS_SERVERS="8.8.8.8,8.8.4.4" ``` </CodeGroup> If you're affected by our [DNS timeouts](/support/known-issues#dns-timeouts), try setting a DNS server manually using this option that doesn't use more than **4** dots in the server name. * Acceptable values: `8.8.8.8`, `my.custom.local.server`. * Not acceptable values: `foo`, `my.awesome.custom.local.dns.server`. If the DNS server cannot be reached the agent will fall back on the host's DNS configuration and output a message in the `appsignal.log` file: `A problem occurred while setting DNS servers`. ## enable\_active\_support\_event\_log\_reporter <a /> | Field | Value | | ----------------------- | ---------------------------------------------------- | | Config file key | `enable_active_support_event_log_reporter` | | System environment key | `APPSIGNAL_ENABLE_ACTIVE_SUPPORT_EVENT_LOG_REPORTER` | | Required | no | | Type | `Boolean` | | Default value | `true` | | Available since version | `4.8.0` | ### Description Enables the `ActiveSupport::EventReporter` [structured event reporting](https://edgeapi.rubyonrails.org/classes/ActiveSupport/EventReporter.html) integration. When enabled, the AppSignal integration subscribes to events emitted by `ActiveSupport::EventReporter`, and report them as logs. ## enable\_allocation\_tracking <a /> | Field | Value | | ----------------------- | -------------------------------------- | | Config file key | `enable_allocation_tracking` | | System environment key | `APPSIGNAL_ENABLE_ALLOCATION_TRACKING` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `true` | | Available since version | `1.0.0` | ### Description Set this option to `false` to disable tracking of the number of allocated objects in Ruby. ## enable\_at\_exit\_hook <a /> | Field | Value | | ----------------------- | ------------------------------------ | | Config file key | `enable_at_exit_hook` | | System environment key | `APPSIGNAL_ENABLE_AT_EXIT_HOOK` | | Required | no | | Type | `String` | | Default value | 'on\_error' / 'always' on containers | | Available since version | `4.5.8` | ### Description Configure how AppSignal shuts down when the application shuts down. This will determine if it calls `Appsignal.stop` automatically, which will flush the data to the extension and the agent. This option has three possible values: * `always`: Always call `Appsignal.stop` when the program exits. On (Docker) containers it's automatically set to this value. * `never`: Never call `Appsignal.stop` when the program exits. The default value when the program doesn't run on a (Docker) container. * `on_error`: Call `Appsignal.stop` when the program exits with an error. For more information, see our [instrumentation for scripts and background jobs page](/ruby/instrumentation/background-jobs). ## enable\_at\_exit\_reporter <a /> | Field | Value | | ----------------------- | ----------------------------------- | | Config file key | `enable_at_exit_reporter` | | System environment key | `APPSIGNAL_ENABLE_AT_EXIT_REPORTER` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `true` | | Available since version | `4.0.0` | ### Description Set to `true` to report the last error that caused the process to quit. The reported error is usually the error that crashes the process. If the Ruby gem already reported the error, it will not report it again. Errors reported via this mechanism are added to the "unhandled" namespace. Add this code to the start of the application on short-lived containers and serverless functions to ensure the error gets flushed before the system shuts down. ```ruby Ruby theme={null} at_exit { sleep 5 } ``` ## enable\_frontend\_error\_catching <a /> | Field | Value | | ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | | Config file key | `enable_frontend_error_catching` | | System environment key | `APPSIGNAL_ENABLE_FRONTEND_ERROR_CATCHING` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `false` | | Available since version | `1.0.0` | | | <ul><li>`3.0.0`: Removed from the gem. See our [upgrade guide](/ruby/installation/upgrade-from-2-to-3) for more information.</li></ul> | ### Description Enable the experimental front-end error catching system. This will add a route to your app on `/appsignal_error_catcher` that can be used to catch JavaScript error and send them to AppSignal. You can configure this route with [`frontend_error_catching_path`](#option-frontend_error_catching_path). ## enable\_gvl\_global\_timer <a /> | Field | Value | | ----------------------- | ----------------------------------- | | Config file key | `enable_gvl_global_timer` | | System environment key | `APPSIGNAL_ENABLE_GVL_GLOBAL_TIMER` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `true` | | Available since version | `3.3.9` | ### Description Set this option to `false` to disable the [GVL global timer instrumentation](/ruby/integrations/global-vm-lock#waiting-threads). This configuration option has no effect if GVLTools is not installed. ## enable\_gvl\_waiting\_threads <a /> | Field | Value | | ----------------------- | -------------------------------------- | | Config file key | `enable_gvl_waiting_threads` | | System environment key | `APPSIGNAL_ENABLE_GVL_WAITING_THREADS` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `true` | | Available since version | `3.3.9` | ### Description Set this option to `false` to disable the [GVL waiting threads instrumentation](/ruby/integrations/global-vm-lock#waiting-threads). This configuration option has no effect if GVLTools is not installed. ## enable\_host\_metrics <a /> | Field | Value | | ----------------------- | ------------------------------- | | Config file key | `enable_host_metrics` | | System environment key | `APPSIGNAL_ENABLE_HOST_METRICS` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | \`\`true` / detected by system` | | Available since version | `1.2.0` | ### Description Set this option to `false` to disable [host metrics](/metrics/host-metrics) collection. On Heroku and Dokku host metrics are disabled by default. This is done because these systems will report inaccurate metrics from within the containers. Host metrics collection on these systems cannot be enabled. For Heroku, use the [Heroku log drain](/heroku/host-metrics) instead. ## enable\_minutely\_probes <a /> | Field | Value | | ----------------------- | --------------------------------------------------------------- | | Config file key | `enable_minutely_probes` | | System environment key | `APPSIGNAL_ENABLE_MINUTELY_PROBES` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `true` | | Available since version | `1.3.0` | | | <ul><li>`2.9.0`: Default value was changed to `true`.</li></ul> | ### Description Enables the [minutely probes](/ruby/instrumentation/minutely-probes) system. ## enable\_nginx\_metrics <a /> | Field | Value | | ----------------------- | -------------------------------- | | Config file key | `enable_nginx_metrics` | | System environment key | `APPSIGNAL_ENABLE_NGINX_METRICS` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `false` | | Available since version | `3.3.4` | ### Description Set to `true` to enable the NGINX metrics server. [See the NGINX metrics documentation for details.](/metrics/nginx) When enabled, the AppSignal agent will listen to a `localhost`-bound server on port 27649. If you're running several AppSignal-instrumented applications in the same server, this configuration option can only be enabled in one of them. ## enable\_rails\_error\_reporter <a /> | Field | Value | | ----------------------- | --------------------------------------- | | Config file key | `enable_rails_error_reporter` | | System environment key | `APPSIGNAL_ENABLE_RAILS_ERROR_REPORTER` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `true` | | Available since version | `3.4.1` | ### Description Set to `false` to disable the Rails error reporter subscriber. [See the Rails documentation for details.](/ruby/integrations/rails) ## enable\_rake\_performance\_instrumentation <a /> | Field | Value | | ----------------------- | --------------------------------------------------- | | Config file key | `enable_rake_performance_instrumentation` | | System environment key | `APPSIGNAL_ENABLE_RAKE_PERFORMANCE_INSTRUMENTATION` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `false` | | Available since version | `3.10.0` | ### Description Enable performance instrumentation for Rake tasks. By default, the [Rake instrumentation](/ruby/integrations/rake) only reports errors. ## enable\_statsd <a /> | Field | Value | | ----------------------- | -------------------------- | | Config file key | `enable_statsd` | | System environment key | `APPSIGNAL_ENABLE_STATSD` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `true` | | Available since version | `3.0.14` | ### Description Enables the [StatsD server](/standalone-agent/statsd) in the AppSignal agent. When enabled, the AppSignal agent will listen to a `localhost`-bound server on port 8125. If you're running several AppSignal-instrumented applications in the same server, this configuration option can only be enabled in one of them. ## endpoint <a /> | Field | Value | | ----------------------- | ------------------------------------------------------------------------- | | Config file key | `endpoint` | | System environment key | `APPSIGNAL_PUSH_API_ENDPOINT` | | Required | no | | Type | `String` | | Default value | `https://push.appsignal.com` | | Available since version | `0.1.0` | | | <ul><li>`1.0.0`: Support for system environment variable added.</li></ul> | ### Description Configure the endpoint to send data to AppSignal. This setting will not have to be changed. ## files\_world\_accessible <a /> | Field | Value | | ----------------------- | ---------------------------------- | | Config file key | `files_world_accessible` | | System environment key | `APPSIGNAL_FILES_WORLD_ACCESSIBLE` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `true` | | Available since version | `2.3.6` | ### Description If this is set to `true` the [AppSignal working directory](/appsignal/how-appsignal-operates#working-directory) that is created is accessible for all users (Unix permissions `0666`). This is often necessary because processes for the same app run under a different user. Set to `false` to disable this behaviour (Unix permissions `0644`). ## filter\_metadata <a /> | Field | Value | | ----------------------- | --------------------------- | | Config file key | `filter_metadata` | | System environment key | `APPSIGNAL_FILTER_METADATA` | | Required | no | | Type | `Array<String>` | | Default value | `[]` | | Available since version | `3.4.5` | ### Description The AppSignal Ruby gem stores metadata about requests and background jobs on samples by default, like request path, request method, request id, background queue, job id and job retry count. These metadata values will be shown in the tags box. If any of these metadata values contain PII or other senstive data, use this config option to filter out metadata by key. Set the `filter_metadata` option to a list of metadata keys that should be filtered out. You can configure this with a list of keys in the configuration file. When filtered the metadata will not be visible in the AppSignal UI. <CodeGroup> ```ruby title="config/appsignal.rb" theme={null} Appsignal.configure do |config| config.filter_metadata += ["path", "request_id"] end ``` ```yaml title="config/appsignal.yml" theme={null} default: &defaults filter_metadata: - path - request_id ``` </CodeGroup> ## filter\_parameters <a /> | Field | Value | | ----------------------- | ----------------------------------------------------------------------------------------------------------------- | | Config file key | `filter_parameters` | | System environment key | `APPSIGNAL_FILTER_PARAMETERS` | | Required | no | | Type | `Array<String>` | | Default value | `[]` | | Available since version | `1.3.0` | | | <ul><li>`2.3.0`: This config option is also used for argument filtering in background job integrations.</li></ul> | ### Description List of parameter keys that should be ignored using AppSignal filtering. Their values will be replaced with `[FILTERED]` when transmitted to AppSignal. You can configure this with a list of keys in the configuration file. <CodeGroup> ```ruby title="config/appsignal.rb" theme={null} Appsignal.configure do |config| config.filter_parameters += ["password", "email", "api_token", "token"] end ``` ```yaml YAML theme={null} # config/appsignal.yml default: &defaults filter_parameters: - password - email - api_token - token ``` </CodeGroup> Read more about [parameter filtering](/application/parameter-filtering). ## filter\_session\_data <a /> | Field | Value | | ----------------------- | ------------------------------------------------------------------------- | | Config file key | `filter_session_data` | | System environment key | `APPSIGNAL_FILTER_SESSION_DATA` | | Required | no | | Type | `Array<String>` | | Default value | `[]` | | Available since version | `2.6.0` | | | <ul><li>An upgrade to version `2.6.1` or higher is recommended.</li></ul> | ### Description List of session data keys that should be ignored using AppSignal filtering. Their values will be replaced with `[FILTERED]` when transmitted to AppSignal. You can configure this with a list of keys in the configuration file. <CodeGroup> ```ruby title="config/appsignal.rb" theme={null} Appsignal.configure do |config| config.filter_session_data += ["name", "email", "api_token", "token"] end ``` ```yaml YAML theme={null} # config/appsignal.yml default: &defaults filter_session_data: - name - email - api_token - token ``` </CodeGroup> Read more about [session data filtering](/application/session-data-filtering). ## host\_role <a /> | Field | Value | | ----------------------- | ------------------------------ | | Config file key | `host_role` | | System environment key | `APPSIGNAL_HOST_ROLE` | | Required | no | | Type | `String` | | Default value | nil (This is unset by default) | | Available since version | `3.4.11` | ### Description Group hosts by role and generate metrics based on this role. One such metric is the `reporting_hosts` counter metric. A good role indicates what the main role of the server is, like "webserver", "processor", "api", "database", "loadbalancer", etc. ## hostname <a /> | Field | Value | | ----------------------- | -------------------- | | Config file key | `hostname` | | System environment key | `APPSIGNAL_HOSTNAME` | | Required | no | | Type | `String` | | Default value | detected from system | | Available since version | `1.3.6` | ### Description This overrides the server's hostname. Useful for when you're unable to set a custom hostname or when a nondescript id is generated for you on hosting services. ## http\_proxy <a /> | Field | Value | | ----------------------- | ------------------------------ | | Config file key | `http_proxy` | | System environment key | `APPSIGNAL_HTTP_PROXY` | | Required | no | | Type | `String` | | Default value | nil (This is unset by default) | | Available since version | `0.11.13` | ### Description If you require the agent to connect to the Internet via a proxy set the complete proxy URL in this configuration key. ## ignore\_actions <a /> | Field | Value | | ----------------------- | -------------------------- | | Config file key | `ignore_actions` | | System environment key | `APPSIGNAL_IGNORE_ACTIONS` | | Required | no | | Type | `Array<String>` | | Default value | `[]` | | Available since version | `0.10.0` | ### Description With this config option you can specify a list of actions that will be ignored by AppSignal. Everything that happens including exceptions will not be transmitted to AppSignal. This can be useful to ignore health check endpoints or other actions that you don't want to monitor. Read more about [ignoring actions](/guides/filter-data/ignore-actions). ## ignore\_errors <a /> | Field | Value | | ----------------------- | ------------------------- | | Config file key | `ignore_errors` | | System environment key | `APPSIGNAL_IGNORE_ERRORS` | | Required | no | | Type | `Array<String>` | | Default value | `[]` | | Available since version | `0.1.0` | ### Description List of error classes that will be ignored. Any exception raised with this error class will not be transmitted to AppSignal. Read more about [ignoring errors](/guides/filter-data/ignore-errors). ## ignore\_logs <a /> | Field | Value | | ----------------------- | ----------------------- | | Config file key | `ignore_logs` | | System environment key | `APPSIGNAL_IGNORE_LOGS` | | Required | no | | Type | `Array<String>` | | Default value | `[]` | | Available since version | `3.7.0` | ### Description List of log messages that will be ignored. Any log message containing any of the elements of the list will not be transmitted to AppSignal. A small subset of regex syntax is supported, read more about it in our [Ignore Logs](/guides/filter-data/ignore-logs) guide. ## ignore\_namespaces <a /> | Field | Value | | ----------------------- | ----------------------------- | | Config file key | `ignore_namespaces` | | System environment key | `APPSIGNAL_IGNORE_NAMESPACES` | | Required | no | | Type | `Array<String>` | | Default value | `[]` | | Available since version | `2.3.0` | ### Description List of namespaces that will be ignored. Any error raised or slow request that occurs in this namespace will not be send to AppSignal. Read more about [namespaces](/application/namespaces). ## instrument\_code\_ownership <a /> | Field | Value | | ----------------------- | ------------------------------------- | | Config file key | `instrument_code_ownership` | | System environment key | `APPSIGNAL_INSTRUMENT_CODE_OWNERSHIP` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `true` | | Available since version | `4.7.1` | ### Description Whether to automatically instrument the [CodeOwnership gem](/ruby/integrations/code-ownership), can be `true` or `false`. ## instrument\_http\_rb <a /> | Field | Value | | ----------------------- | ------------------------------ | | Config file key | `instrument_http_rb` | | System environment key | `APPSIGNAL_INSTRUMENT_HTTP_RB` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `true` | | Available since version | `3.2.0` | ### Description Enable or disable the instrumentation for the [http.rb Ruby gem](https://github.com/httprb/http). Enabled by default. ## instrument\_net\_http <a /> | Field | Value | | ----------------------- | ------------------------------- | | Config file key | `instrument_net_http` | | System environment key | `APPSIGNAL_INSTRUMENT_NET_HTTP` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `true` | | Available since version | `0.9.0` | ### Description Whether to add instrumentation for `net/http` calls, can be `true` or `false`. ## instrument\_ownership <a /> | Field | Value | | ----------------------- | -------------------------------- | | Config file key | `instrument_ownership` | | System environment key | `APPSIGNAL_INSTRUMENT_OWNERSHIP` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `true` | | Available since version | `4.3.3` | ### Description Whether to automatically instrument the [Ownership gem](/ruby/integrations/ownership), can be `true` or `false`. ## instrument\_redis <a /> | Field | Value | | ----------------------- | ---------------------------- | | Config file key | `instrument_redis` | | System environment key | `APPSIGNAL_INSTRUMENT_REDIS` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `true` | | Available since version | `1.0.0` | ### Description Whether to enable the instrumentation for Redis queries using the [Redis gem](https://rubygems.org/gems/redis), can be `true` or `false`. ## instrument\_sequel <a /> | Field | Value | | ----------------------- | ----------------------------- | | Config file key | `instrument_sequel` | | System environment key | `APPSIGNAL_INSTRUMENT_SEQUEL` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `true` | | Available since version | `1.0.0` | ### Description Whether to add instrumentation for `sequel` queries using the [Sequel gem integration](/ruby/integrations/sequel), can be `true` or `false`. ## log <a /> | Field | Value | | ----------------------- | --------------- | | Config file key | `log` | | System environment key | `APPSIGNAL_LOG` | | Required | no | | Type | `String` | | Default value | `file` | | Available since version | `2.0.0` | ### Description <Note> This option configures what logger that AppSignal's internal logging functionality will use and does not affect the [logging feature](/logging). **Note**: The [AppSignal agent](/appsignal/how-appsignal-operates), which is used by the integration, will always write to the "appsignal.log" file. </Note> Select which logger the AppSignal integration will use. Accepted values are `file` and `stdout`. See also the `log_path` configuration. * `file` (default) * Write all AppSignal logs to the file system. * `stdout` (default on [Heroku](https://heroku.com)) * Print AppSignal logs in the parent process' STDOUT instead of to a file. Useful with hosting solutions such as container systems and Heroku. ## log\_level <a /> | Field | Value | | ----------------------- | --------------------- | | Config file key | `log_level` | | System environment key | `APPSIGNAL_LOG_LEVEL` | | Required | no | | Type | `String` | | Default value | `info` | | Available since version | `3.0.16` | ### Description <Note> This option sets the severity level of AppSignal's internal logger and does not affect the [logging feature](/logging). </Note> Set the severity level of AppSignal's internal logger. If it is configured to "info" it will log all error, warning and info messages, but not log the debug messages. Setting it to the levels "debug" or "trace" is usually only needed on request from support. Setting the level to "debug"/"trace" could have a slight impact on the disk usage and IO, especially on high-traffic sites. CPU overhead is minimal with the debug option enabled. Accepted values: * error * warning * info * debug * trace ## log\_path <a /> | Field | Value | | ----------------------- | -------------------- | | Config file key | `log_path` | | System environment key | `APPSIGNAL_LOG_PATH` | | Required | no | | Type | `String` | | Default value | `./log` | | Available since version | `1.0.0` | ### Description <Note> This option configures the location of AppSignal's internal logging file and does not affect the [logging feature](/logging). <br /> **Note**: The specified path cannot contain Operating Specific file system abstractions, such as the homedir symbol `~` for \*NIX systems. This will be seen as a malformed path. </Note> Override the location of the path (directory) where the `appsignal.log` file can be written to. ## nginx\_port <a /> | Field | Value | | ----------------------- | ---------------------- | | Config file key | `nginx_port` | | System environment key | `APPSIGNAL_NGINX_PORT` | | Required | no | | Type | `Integer` | | Default value | `27649` | | Available since version | `4.5.15` | ### Description Configure the port on which the NGINX metrics server is exposed. When AppSignal receives NGINX metrics, it listens on a `localhost`-bound server, by default on port 27649. If you're running several AppSignal-instrumented applications in the same server with NGINX metrics enabled, use this option to configure each application to listen on a different port. ## ownership\_set\_namespace <a /> | Field | Value | | ----------------------- | ----------------------------------- | | Config file key | `ownership_set_namespace` | | System environment key | `APPSIGNAL_OWNERSHIP_SET_NAMESPACE` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `false` | | Available since version | `4.3.3` | ### Description Whether the [Ownership gem instrumentation](/ruby/integrations/ownership) should set the namespace of a sample to its owner, can be `true` or `false`. ## request\_headers <a /> | Field | Value | | ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Config file key | `request_headers` | | System environment key | `APPSIGNAL_REQUEST_HEADERS` | | Required | no | | Type | `Array<String>` | | Default value | `["HTTP_ACCEPT", "HTTP_ACCEPT_CHARSET", "HTTP_ACCEPT_ENCODING", "HTTP_ACCEPT_LANGUAGE", "HTTP_CACHE_CONTROL", "HTTP_CONNECTION", "CONTENT_LENGTH", "PATH_INFO", "HTTP_RANGE", "REQUEST_METHOD", "REQUEST_PATH", "SERVER_NAME", "SERVER_PORT", "SERVER_PROTOCOL"]` | | Available since version | `2.6.0` | | | <ul><li>Upgrade to `2.6.1` or higher is recommend.</li><li>Since `3.5.6` `REQUEST_URI` is no longer included by default. Now `REQUEST_PATH` is included instead.</li></ul> | ### Description The `request_headers` config option contains a list of HTTP request headers which are read and stored by the AppSignal Ruby gem. This `request_headers` config option is an *allowlist*, which means that it will only take headers as specified by this config option. If this config option is unset it will use the AppSignal default. <CodeGroup> ```ruby title="config/appsignal.rb" theme={null} Appsignal.configure do |config| # Add a request header config.request_headers << "PATH_INFO" # Remove a request header config.request_headers.delete("PATH_INFO") end ``` ```yaml title="config/appsignal.yml" theme={null} # To add an additional request header it's necessary to list all default headers too default: &defaults request_headers: - HTTP_ACCEPT - HTTP_ACCEPT_CHARSET - HTTP_ACCEPT_ENCODING - HTTP_ACCEPT_LANGUAGE - HTTP_CACHE_CONTROL - HTTP_CONNECTION - CONTENT_LENGTH - PATH_INFO - HTTP_RANGE - REQUEST_METHOD - REQUEST_PATH - SERVER_NAME - SERVER_PORT - SERVER_PROTOCOL ``` </CodeGroup> Note that AppSignal reads the headers from your app and they may not match 1 to 1 with what is being sent in the browser/client. In [Rack apps](https://rack.github.io/) ([Rails](/ruby/integrations/rails), [Sinatra](/ruby/integrations/sinatra), etc) all custom headers are prefixed with the `HTTP_` string, all header names are uppercased and dashes (`-`) are replaced with underscores (`_`). For example, the `X-Hub-Signature` header can be access by your app and AppSignal with the `HTTP_X_HUB_SIGNATURE` name. To configure AppSignal to not store any HTTP request headers on AppSignal transactions, configure the option with an empty array. <CodeGroup> ```ruby title="config/appsignal.rb" theme={null} Appsignal.configure do |config| config.request_headers = [] end ``` ```yaml title="config/appsignal.yml" theme={null} default: &defaults request_headers: [] ``` </CodeGroup> ## revision <a /> | Field | Value | | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | Config file key | `revision` | | System environment key | `APP_REVISION` | | Required | no | | Type | `String` | | Default value | nil (This is unset by default) | | Available since version | `2.6.0` | | | <ul><li>An upgrade to `2.6.1` or higher is recommended when using this option.</li><li>`2.9.13`: Auto detection for Heroku deploys with the Dyno Metadata labs feature enabled.</li><li>`2.9.14`: Do not use this release if you depend on the Heroku dyno metadata detection.</li><li>`3.4.7`: Auto detection for Render deploys.</li><li>`3.7.5`: Auto detection for Kamal deploys.</li><li>`4.5.18`: Auto detection for Capistrano deploys.</li><li>`4.5.18`: Auto detection for Hatchbox.io deploys.</li></ul> | ### Description Set the app revision to report the currently running version of your app. AppSignal will create a deploy marker when this value changes, and tag all incoming data with the current revision. When your application is deployed using Kamal, or when it is deployed to Render, or when it is deployed to Heroku and the [Heroku Labs: Dyno Metadata](https://devcenter.heroku.com/articles/dyno-metadata) feature is enabled, the AppSignal integration will automatically detect the Git commit of the current deployment and use it as the revision. You can overwrite the automatically detected revisions in Heroku, Render or Kamal by manually setting the `revision` config option to a custom value. Read more about deploy markers in the [deploy markers topic](/application/markers/deploy-markers). ## running\_in\_container <a /> | Field | Value | | ----------------------- | ------------------------------------------------------------ | | Config file key | `running_in_container` | | System environment key | `APPSIGNAL_RUNNING_IN_CONTAINER` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | detected by agent | | Available since version | `1.0.0` | | | <ul><li>Automatically detected since version `2.0`</li></ul> | ### Description AppSignal expects to be running on the same machine between different deploys. Set this key to `true` if the application is running in a container, such as with Docker. Newer versions of the AppSignal integration automatically detect its container environment, so no manual configuration is necessary. If you're having trouble with the automatic detection, please [contact support](mailto:support@appsignal.com). This option is set to `true` automatically on [Heroku](http://heroku.com/). ## send\_environment\_metadata <a /> | Field | Value | | ----------------------- | ------------------------------------- | | Config file key | `send_environment_metadata` | | System environment key | `APPSIGNAL_SEND_ENVIRONMENT_METADATA` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `true` | | Available since version | `2.11.0` | ### Description Send environment metadata about the app. For more information please read about [environment metadata](/application/environment-metadata). ## send\_params <a /> | Field | Value | | ----------------------- | --------------------------------------------------------------------------- | | Config file key | `send_params` | | System environment key | `APPSIGNAL_SEND_PARAMS` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `true` | | Available since version | `0.9.0` | | | <ul><li>`1.3.0`: Support added for the system environment option.</li></ul> | ### Description Whether to skip sending request parameters to AppSignal. For more information please read about [send\_params](/application/parameter-filtering) in filtering request parameters. ## send\_session\_data <a /> | Field | Value | | ----------------------- | ----------------------------- | | Config file key | `send_session_data` | | System environment key | `APPSIGNAL_SEND_SESSION_DATA` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `true` | | Available since version | `3.0.20` | ### Description Set this option to `false` to not send any session data with exception traces and performance issue samples. For more information please read about [request session data filtering](/application/session-data-filtering). ## sidekiq\_report\_errors <a /> | Field | Value | | ----------------------- | --------------------------------- | | Config file key | `sidekiq_report_errors` | | System environment key | `APPSIGNAL_SIDEKIQ_REPORT_ERRORS` | | Required | no | | Type | `String` | | Default value | `all` | | Available since version | `3.9.0` | ### Description Configure the reporting of errors that occur in [Sidekiq](/ruby/integrations/sidekiq) jobs. Accepted values: * `all`: Report all errors for every execution of jobs, including retries. * `discard`: Report errors when the job is discarded due to the error. Use this option to only report errors when all job retries have been exhausted. * `none`: Report no errors for jobs, including retries. Useful for custom error reporting. <Note> **Note**: The `discard` option only works on Sidekiq 5.1 and newer. On lower versions `discard` is read as `all`. </Note> ## skip\_session\_data <a /> | Field | Value | | ----------------------- | ---------------------------------------------------------------------------------------------------- | | Config file key | `skip_session_data` | | System environment key | `APPSIGNAL_SKIP_SESSION_DATA` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `false` | | Available since version | `0.11.0` | | | <ul><li>`3.0.20`: Deprecated in favor of [`send_session_data`](#option-send_session_data).</li></ul> | ### Description <Warning> **Warning**: This config option is deprecated in Ruby gem 3.0.20. Please use the [`send_session_data`](#option-send_session_data) option instead for newer versions of the Ruby gem. </Warning> ## statsd\_port <a /> | Field | Value | | ----------------------- | ----------------------- | | Config file key | `statsd_port` | | System environment key | `APPSIGNAL_STATSD_PORT` | | Required | no | | Type | `Integer` | | Default value | `8125` | | Available since version | `3.4.3` | ### Description Set this option to configure the StatsD HTTP server port of the AppSignal agent process. Configure this port if another process is already running on the machine that is also using this port to avoid conflicts. ## transaction\_debug\_mode <a /> | Field | Value | | ----------------------- | ----------------------------------------------------------------------------------------------------------------- | | Config file key | `transaction_debug_mode` | | System environment key | `APPSIGNAL_TRANSACTION_DEBUG_MODE` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `false` | | Available since version | `2.9.18` | | | <ul><li>Deprecated since version 3.0.16 in favor of the [`log_level` config option](#option-log_level).</li></ul> | ### Description <Warning> **Warning**: This config option is deprecated in Ruby gem 3.0.16. Please use the [`log_level`](#option-log_level) option instead for Ruby gem 3.0.16 and newer. </Warning> Enable transaction debug mode. This enables very detailed logging of transactions and events which is useful when developing integrations or when events aren not tracked as expected. The log is only written if the general `debug` option is on as well. <Note> This option sets the severity level of AppSignal's internal logger and does not affect the [logging feature](/logging). </Note> ## working\_dir\_path <a /> | Field | Value | | ---------------------- | ---------------------------- | | Config file key | `working_dir_path` | | System environment key | `APPSIGNAL_WORKING_DIR_PATH` | | Required | no | | Type | `String` | | Default value | detected by agent | ### Description <Warning> **Warning**: This config option is deprecated in Ruby gem 2.7.0. Please use the [`working_directory_path`](#option-working_directory_path) option instead for Ruby gem 2.7.0 and newer. </Warning> <Note> Override the location where AppSignal for Ruby creates a working directory. See [`working_directory_path`](#appsignal_working_directory_path-working_directory_path) for the behavior it is applicable. This config option appends `/appsignal` to the specified path, where [`working_directory_path`](#appsignal_working_directory_path-working_directory_path) does not. </Note> <Note> **Note**: The specified path cannot contain Operating Specific file system abstractions, such as the homedir symbol `~` for \*NIX systems. This will be seen as a malformed path. </Note> ## working\_directory\_path <a /> | Field | Value | | ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Config file key | `working_directory_path` | | System environment key | `APPSIGNAL_WORKING_DIRECTORY_PATH` | | Required | no | | Type | `String` | | Default value | detected by agent | | Available since version | `2.7.0` | | | <ul><li>`2.10.12`: Support added for the system environment option.</li><li>Please use the [`working_dir_path`](#option-working_dir_path) option on versions older than 2.7.0.</li></ul> | ### Description Override the location where AppSignal for Ruby can store temporary files. Use this option if the default location is not suitable. See our [how AppSignal operates](/appsignal/how-appsignal-operates) page for more information about the purpose of this working directory. If you are running multiple applications using AppSignal on the same server, use this configuration option to select different working directories for every AppSignal instance, otherwise the two instances could conflict with one another. For more information on this scenario see our [running multiple applications on one host](/guides/application/multiple-applications-on-one-host) documentation. <CodeGroup> ```ruby title="config/appsignal.rb" theme={null} Appsignal.configure do |config| config.working_directory_path = "/tmp/project_1/" end ``` ```yaml title="config/appsignal.yml" theme={null} default: &defaults working_directory_path: "/tmp/project_1/" ``` </CodeGroup> <Note> **Note**: The specified path cannot contain Operating Specific file system abstractions, such as the homedir symbol `~` for \*NIX systems. This will be seen as a malformed path. </Note> # Installing AppSignal for Ruby Source: https://docs.appsignal.com/ruby/installation Please follow the [installation guide](/guides/new-application) first, when adding a new application to AppSignal. ## Requirements Before you can compile the AppSignal gem make sure the build/compilation tools are installed for your system. Please check the [Supported Operating Systems](/support/operating-systems) page for any system dependencies that may be required. ## Installing the gem We recommend you install and manage the AppSignal gem dependency with [Bundler](http://bundler.io/). Add the following line to your `Gemfile`. <CodeGroup> ```ruby Ruby theme={null} # Gemfile source "https://rubygems.org" gem "appsignal" ``` </CodeGroup> Then run `bundle install` to install the gem. To install AppSignal in your application we recommend you run the `appsignal install` command. Please provide it with your [Push API key](/appsignal/terminology#push-api-key) to configure it properly. <CodeGroup> ```sh Shell theme={null} bundle exec appsignal install YOUR_PUSH_API_KEY ``` </CodeGroup> This will present you with an installation script that can integrate automatically in some frameworks and gems and will allow you to configure AppSignal. For more information on how to integrate AppSignal into your application see the [integrations documentation](/ruby/integrations) to see what steps are necessary. *** <Note> πŸ“– Continue with our [installation guide](/guides/new-application). </Note> ## Uninstall Uninstall AppSignal from your app by following the steps below. When these steps are completed your app will no longer send data to the AppSignal servers. 1. In the `Gemfile` of your app, delete the `gem "appsignal"` line. 2. Run `bundle install` to update your `Gemfile.lock` with the removed gem state. 3. Remove any AppSignal [configuration files](/ruby/configuration/) from your app. * Configuration file location: `config/appsignal.rb` or `config/appsignal.yml` 4. Remove any system environment variables from your development, staging, production, etc. hosts. * Environment variables prefixed with `APPSIGNAL_` * Environment variable [`APP_REVISION`](/ruby/configuration/options#option-revision) 5. Commit, deploy and restart your app. * This will make sure the AppSignal servers won't continue to receive data from your app. 6. Optional: Make sure no `appsignal-agent` processes are running in the background. * Check the output of `ps aux | grep appsignal-agent` and kill the processes still running. 7. Finally, [remove the app](/guides/application/deleting-applications) on AppSignal.com. <Note> πŸ“– Continue with our [uninstall guide](/guides/application/deleting-applications). </Note> # Upgrade from AppSignal for Ruby gem 2.x to 3.x Source: https://docs.appsignal.com/ruby/installation/upgrade-from-2-to-3 AppSignal for Ruby 3.0 is a major release as it changes the way it instruments other gems, removes support for older Ruby versions, removes the integrated JavaScript integration and removes previously deprecated modules. Follow this guide to make the upgrade process smoother. ## Upgrade to the latest 2.x series Before upgrading to AppSignal for Ruby gem 3.0, please first upgrade to the latest gem from the 2.x series. This version will log and print deprecation warnings for things that will be removed in version 3.x of the gem. Run the tests for your app the gem is integrated with, fix any deprecation warnings and errors you may encounter. This upgrade step will make upgrading an easier process. First, in the app's `Gemfile`, update the version lock to `~> 2.0` and run `bundle update appsignal` in a terminal in the same directory as the `Gemfile`. <CodeGroup> ```ruby Ruby theme={null} # Gemfile gem "appsignal", "~> 2.0" ``` </CodeGroup> After all deprecation warnings have been resolved that appeared during testing and running the app, remove the version lock from the `Gemfile` and run `bundle update appsignal` again to update to AppSignal for Ruby 3.0. <CodeGroup> ```ruby Ruby theme={null} # Gemfile gem "appsignal" ``` </CodeGroup> ## Removed Ruby 1.9 supported The 3.x series of the Ruby gem will no longer support Ruby 1.9 and older versions. Ruby 1.9 has been End of Life since [23th of February 2015](https://www.ruby-lang.org/en/news/2015/02/23/support-for-ruby-1-9-3-has-ended/) and should no longer be used in production. Future versions of the AppSignal for Ruby gem may drop other End of Life versions of Ruby. Please upgrade to a newer version of Ruby to continue using AppSignal for Ruby moving forward. ## Compatibility with other instrumentation gems In the 3.x series the AppSignal for Ruby gem changed the internals of all its integrations of other gems. Instead of aliasing methods to provide instrumentation, the 3.x series uses `Module.prepend` (introduced in Ruby 2.0), a method to include Ruby Modules in classes and ensuring the included module gets called first. **What does this means for your apps?** Other instrumentation gems may either use the method aliasing or `Module.prepend` method to providing instrumentation. These instrumentation methods are **incompatible** with one another if used on the same Ruby methods. If one gem uses method aliasing, and another `Module.prepend` the app will be caught in a loop and raise a [`stack level too deep (SystemStackError)`][module prepend issue]. The Ruby ecosystem seems to be moving towards the `Module.prepend` method of providing instrumentation so the AppSignal gem has updated its instrumentation method to be more compatible with other gems. If an app starts encountering this issue with the AppSignal for Ruby 3.x series, upgrade other APM and error reporting gems in the app. They may have been updated to instrument using `Module.prepend` as well. If the issue persists, please contact the maintainers of the other gems to update their implementation to `Module.prepend`, and downgrade the AppSignal for Ruby gem to the 2.x series for now. Please also [inform us][contact], so we can keep a list of compatible gems. For more information and background of this change, see [issue 603 on the Ruby gem issue tracker][module prepend issue]. ## Moved modules Some modules in the gem have been moved or renamed. The 2.x series of the gem will print a warning if it encounters any with the new location of the called module. This warning is printed by a fallback when the old module name is called. This warning will no longer be printed if the new module name is being called instead. If an app extended or monkeypatched an AppSignal module, the module name needs to be updated for the patch to work again. Do be warned that we do not provide support for these patches. If a private module has been removed without replacement, we do not provide the integration any more or it has been merged into another module. ## Removed JavaScript integration The AppSignal for Ruby gem included a JavaScript exception tracking middleware, which has been removed in the 3.x series. Instead we recommend you use our dedicated [AppSignal for Front-end JavaScript integration](/front-end/). ### Removed options The following options will no longer affect the AppSignal for Ruby gem, it can be removed from your apps. * `enable_frontend_error_catching` - removed config option * `APPSIGNAL_ENABLE_FRONTEND_ERROR_CATCHING` - removed environment variable config option * `frontend_error_catching_path` - removed config option * `APPSIGNAL_FRONTEND_ERROR_CATCHING_PATH` - removed environment variable config option ### Removed classes The following classes have been removed from the Ruby gem and calling them will result in a `NameError`. * `Appsignal::JSExceptionTransaction` - removed JavaScript transaction class * `Appsignal::Rack::JSExceptionCatcher` - removed middleware ## Removed `appsignal notify_of_deploy` command The `appsignal notify_of_deploy` command has been removed. Instead we recommend using the [`revision`](/ruby/configuration/options#option-revision) config option to report deploys more accurately. For more information on the topic of deploy markers, please see our [deploy markers section](/application/markers/deploy-markers). If the `revision` option is not a good replacement for your deploy method, please use our [deploy markers API page](/api/markers) about how to send the request to notify AppSignal of deploys. And see our [Push & deploy page](https://appsignal.com/redirect-to/app?to=info) for your app for an example using your app's config. ## Removed deprecations In AppSignal for Ruby 2.x series and older, some behavior of the AppSignal gem may have been deprecated. Most of these deprecations have been removed in the 3.x series. On the latest release in the AppSignal for Ruby 2.x series, all these deprecations should print an warning to STDERR and to the [`appsignal.log`](/support/debugging#log-location) when still used. Please check the app output and logs while on the latest 2.x series gem and fix all deprecation warnings before upgrading. Each deprecation should print/log a warning with the changes needed to resolve the warning. ## Welcome to 3.x! This guide should cover upgrading most Ruby applications to 3.x. If you have any questions, ran into errors, or would like assistance upgrading to the new version, please don't hesitate to [contact support][contact]. [contact]: mailto:support@appsignal.com [module prepend issue]: https://github.com/appsignal/appsignal-ruby/issues/603 # Upgrade from AppSignal for Ruby gem 3.x to 4.x Source: https://docs.appsignal.com/ruby/installation/upgrade-from-3-to-4 A guide to help applications upgrade from AppSignal for Ruby gem 3 to version 4. AppSignal for Ruby 4.0 is a major release that introduces multiple error support, amendable sample data, changes to how it instruments other gems, how custom instrumentation works, and the removal of previously deprecated modules. Follow this guide to make the upgrade process smoother. ## Upgrade to the latest 3.x series Before upgrading to AppSignal for Ruby gem 4.0, upgrade to the latest gem from the 3.x series. This version will print and log deprecation warnings for things that were removed in version 4.x of the Ruby gem. Run the tests for your app the gem is integrated with and fix any deprecation warnings and errors you may encounter. First, in the app's `Gemfile`, update the version lock to `~> 3.0` and run `bundle update appsignal` in a terminal in the same directory as the `Gemfile`. <CodeGroup> ```ruby Ruby theme={null} # Gemfile gem "appsignal", "~> 3.0" ``` </CodeGroup> Run your applications and fix any deprecation warnings printed to the application's STDERR output and logged in `appsignal.log` during its operation. ## Upgrade to the latest 4.x series After all deprecation warnings are resolved using version 3 of the Ruby gem, remove the version lock from the `Gemfile` and run `bundle update appsignal` again to update AppSignal for Ruby to version 4. <CodeGroup> ```ruby Ruby theme={null} # Gemfile gem "appsignal" ``` </CodeGroup> ## Changes Below are all the notable changes between the latest Ruby gem version 3 and the new version 4. Please go through them and update your application as described. ### Main library * The `Appsignal.start_logger` method is removed. The logger is now automatically started on `Appsignal.start`. Applications need to remove the `Appsignal.start_logger` call. * The AppSignal Ruby gem configuration is frozen after `Appsignal.start` is called. The configuration can no longer be modified after the Ruby gem has started. * The `Appsignal.start` method can only be called once. Subsequent calls are ignored by the Ruby gem. ### Configuration * AppSignal will not start if loading the `config/appsignal.yml` file causes an error. Check the application output or the `appsignal.log` file for any warnings. * Configure AppSignal in Ruby with the new [`Appsignal.configure` helper](/ruby/configuration/load-order#configure-helper). Apps using the `Appsignal.config = Appsignal::Config.new(...)` pattern must update their apps to use this method instead. * The `Appsignal.config =` method is removed. Instead, use the [`Appsignal.configure` helper](/ruby/configuration/load-order#configure-helper) to configure AppSignal in Ruby. * The `skip_session_data` option is removed. Use the [`send_session_data` option](/ruby/configuration/options#option-send_session_data) instead. * The `debug` option is removed. Use the [`log_level: debug` option](/ruby/configuration/options#option-log_level) instead. * The `transaction_debug_mode` option is removed. Use the [`log_level: trace` option](/ruby/configuration/options#option-log_level) instead. * The `working_dir_path` option is removed. Use the [`working_directory_path` option](/ruby/configuration/options#option-working_directory_path) instead. ### Integrations * The `Appsignal::Rack::EventHandler` middleware is added. It will add the `response_status` tag to samples and track a `response_status` metric with the request's response status code. See [our Rack integration docs](/ruby/integrations/rack) for more information. * The `Appsignal::Rack::InstrumentationMiddleware` middleware replaces the `Appsignal::Rack::GenericInstrumentation` middleware. This new middleware does not set the action to "unknown" by default. It is required to set the action name in each app endpoint with `Appsignal.set_action` when only using the `InstrumentationMiddleware` middleware. See [our Rack integration docs](/ruby/integrations/rack) for more information. * `Appsignal::Grape::Middleware` is renamed to `Appsignal::Rack::GrapeMiddleware`. * The `Appsignal::Rack::StreamingListener` is replaced by `Appsignal::Rack::InstrumentationMiddleware`. * The `Appsignal::Hooks::SidekiqPlugin` is removed without replacement. * The Grape, Hanami, Padrino and Sinatra integrations now use the `Appsignal.load` mechanism to integrate with these libraries. Please follow the installation guides for these libraries to update to the new loading mechanism. * [Sinatra](/ruby/integrations/sinatra) * [Hanami](/ruby/integrations/hanami) * [Grape](/ruby/integrations/grape) * [Padrino](/ruby/integrations/padrino) * Using more than one of these libraries or mounting them on a Rails app? [Follow this guide](/ruby/integrations/rack-libraries) as well. * The errors and performance issues reported by our Rake integration are now reported under the "rake" namespace. ### Custom instrumentation * The [`Appsignal.report_error` helper](/ruby/instrumentation/exception-handling) makes it easier to always report errors, without knowing the difference between the `Appsignal.set_error` and `Appsignal.send_error` helpers. <CodeGroup> ```ruby Ruby theme={null} # Before Appsignal.set_error(error) Appsignal.send_error(error, :tag => "value", "custom namespace") # After Appsignal.report_error(error) Appsignal.report_error(error) do Appsignal.set_namespace("custom namespace") Appsignal.add_tags(:tag => "value") end ``` </CodeGroup> * Multiple errors can be reported on one transaction with the [`Appsignal.report_error` helper](/ruby/instrumentation/exception-handling#reporting-multiple-exceptions). * The `Appsignal.monitor_transaction` and `Appsignal.monitor_single_transaction` helpers are replaced by the [`Appsignal.monitor` and `Appsignal.monitor_and_stop` helpers](/ruby/instrumentation/background-jobs). * Note: newer versions of the Ruby gem have [deprecated the `Appsignal.monitor_and_stop` helper](/ruby/instrumentation/background-jobs#stop-requirement). * New helpers for adding tags and sample data (parameters, request headers, session data and custom data) to transactions. See the [customization helpers](/guides/custom-data) documentation for more information. <CodeGroup> ```ruby Ruby theme={null} # Before Appsignal.tag_request(:tag => "value") Appsignal::Transaction.current.set_sample_data( "custom_data", :i18n => { :locale => "en_GB", :default_locale => "en_US" } ) # After Appsignal.add_tags(:tag => "value") Appsignal.add_custom_data( :i18n => { :locale => "en_GB", :default_locale => "en_US" } ) ``` </CodeGroup> * Sample data is amended by default. Adding additional parameters, request headers, session data and custom data will merge it with the previously set values. See the [customization helpers](/guides/custom-data) documentation for more information. * The `Appsignal::Transaction::GenericRequest` helper is removed. Use our [customization helpers](/guides/custom-data) to add metadata to the transaction. * The `appsignal.action` and `appsignal.route` request environment keys are removed. Use the `Appsignal.set_action` helper to set the action name instead. * The `tags` and `namespace` arguments were removed from the `Appsignal.set_error` and `Appsignal.send_error` helpers. Use the block method to customize the transaction before it's sent instead. See [our exception handling guide](/ruby/instrumentation/exception-handling) for more information. * The `Appsignal::Minutely` constant is renamed to `Appsignal::Probes`. * The `Appsignal::Probes.probes.register` method is replaced with `Appsignal::Probes.register`. See [our minutely probes documentation](/ruby/instrumentation/minutely-probes) for more information. * The `Appsignal.set_host_gauge` and `Appsignal.set_process_gauge` helpers are removed without replacement. Instead, tag the metric with the hostname or process ID using the [`Appsignal.set_gauge` helper](/metrics/custom#gauge). * The `Appsignal.listen_for_error` helper is removed without replacement. Instead, manually rescue errors using `rescue => error` and report them using the [`Appsignal.report_error` helper](/ruby/instrumentation/exception-handling#appsignalreport_error). ### Library internals Listed here are changes to library internals that may have previously been used in our documentation or support cases. We recommend you refrain from relying on these anymore. These are private components and may change at any moment. Breaking changes include: * The `Appsignal::Transaction.create` and `Appsignal::Transaction.new` methods no longer accept the `id`, `request`, and `options` arguments. The transaction ID is now automatically generated. * Instead of manually creating a Transaction object, use the [`Appsignal.monitor` helper](/ruby/instrumentation/background-jobs) instead. * To set metadata on the transaction, use our [customization helpers](/guides/custom-data). * The `Appsignal::Transaction#set_http_or_background_action` method is removed. Use the `Appsignal.set_action` helper instead. * The `Appsignal::Transaction#set_http_or_background_queue_start` method is removed. Use the `Appsignal::Transaction#set_queue_start` helper instead. * The `AppSignal::Transaction#params=` helper is removed. Use the [`Appsignal.add_params` helper](/guides/custom-data/request-parameters) instead. ## Welcome to 4.x! This guide should cover upgrading most Ruby applications to AppSignal Ruby gem 4.x. If you have any questions, ran into errors, or would like assistance upgrading to the new version, please don't hesitate to [contact support][contact]. [contact]: mailto:support@appsignal.com # Custom instrumentation for Ruby Source: https://docs.appsignal.com/ruby/instrumentation AppSignal provides many ways to provide more insights in your application by adding more instrumentation or tagging the data that appears in the UI at AppSignal.com. * [Integrating AppSignal](/ruby/instrumentation/integrating-appsignal) * [Instrumentation](/ruby/instrumentation/instrumentation) * [Exception handling](/ruby/instrumentation/exception-handling) * [Breadcrumbs](/ruby/instrumentation/breadcrumbs) * [Ignore instrumentation](/ruby/instrumentation/ignore-instrumentation) * [Scripts and background jobs](/ruby/instrumentation/background-jobs) * [Method instrumentation](/ruby/instrumentation/method-instrumentation) * [Event formatters](/ruby/instrumentation/event-formatters) * [Minutely probes](/ruby/instrumentation/minutely-probes) * [Request queue time](/ruby/instrumentation/request-queue-time) * [Custom marker reporting](/ruby/instrumentation/custom-markers) * [Command line tool](/ruby/command-line) ## Contact us Don't hesitate to [contact us](mailto:support@appsignal.com) if you run into any issues while implementing custom instrumentation. We're here to help. # Instrumentation for scripts and background jobs Source: https://docs.appsignal.com/ruby/instrumentation/background-jobs <VersionRequirements /> AppSignal supports [many gems out-of-the-box][integrations] and doesn't require additional instrumentation to report error and performance data. For custom scripts and libraries we don't support, you can add monitoring by following this guide. ## Monitoring scripts An AppSignal sample is composed of two elements: a transaction and events. Before reporting events with [our instrumentation helpers](#instrumentation-events), you must first create a transaction. Use the `Appsignal.monitor` helper to create a transaction and make it active for the duration of the given block. The monitor helper will report the instrumented code block as performance measurements listed in the Performance section in the AppSignal UI, grouped by action name. It will track the block's duration and report exceptions that occur inside. <CodeGroup> ```ruby Ruby theme={null} class CronJobScript def call Appsignal.monitor( :namespace => "cron", :action => "CronJobScript#call" ) do # Your code end end end ``` </CodeGroup> The `monitor` helper accepts two keyword arguments: * `namespace` (Optional): Customize the namespace of the transaction. Defaults to "web". * `action` (Required): We group the script's samples by this action name for issue creation and notifications. Without an action name, no information about the monitored block is reported, because we don't know how to group the data. ### Set the action name later The `Appsignal.monitor` helper's `action` argument can be left nil or explicitly set to `:set_later`, but only if the `Appsignal.set_action` helper is still called inside the block to set the action name. Without an action name, no data is reported about the instrumented block. This method of setting the action name can be helpful if the action name can only be determined in a processing step inside the block. <CodeGroup> ```ruby Ruby theme={null} class CronJobScript def call Appsignal.monitor( :action => :set_later ) do # Your code # Set action name later Appsignal.set_action("My action name") end end end ``` </CodeGroup> ### Instrumentation events By default, the Ruby gem will report events from [supported integrations][integrations]. These events will appear in the event timeline. Use [our instrumentation helpers](/ruby/instrumentation/instrumentation) to add your own events to the event timeline. This creates a more detailed breakdown of what's happening inside the monitored block. <CodeGroup> ```ruby Ruby theme={null} class CronJobScript def call Appsignal.monitor( :namespace => "cron", :action => "CronJobScript#call" ) do Appsignal.instrument "fetch.plans" do # Complex part of fetching payment plans end Appsignal.instrument "send.invoices" do # Complex part of sending invoices end end end end ``` </CodeGroup> ## Stop requirement For scripts running on short-lived hosts, it is required to stop the AppSignal Ruby gem before the script exits. This will ensure it reports the data from the script to AppSignal before the host shuts down. This behavior is only needed in such scenarios like: * When a scheduled task (a cron job) is run by a hosting service. * When a script is run on a container that starts to run this script and shuts down when the script exits. * When a script is run on a Heroku runner, or similar hosting providers. It is not needed to stop the AppSignal Ruby gem if the host on which the script is started, continues to run after the script has exited. AppSignal is stopped automatically when the script exits and a container or hosting environment like Heroku is detected. This behavior is controlled by the [`enable_at_exit_hook` option](/ruby/configuration/options#option-enable_at_exit_hook). Ensure this option is set to true for scripts that require AppSignal to be stopped, if it's not automatically detected. It may be needed to add an additional `sleep` call of a couple seconds to ensure there's enough time to send all the data. Use the `at_exit` usage example from the code below if needed. <CodeGroup> ```ruby Ruby theme={null} # This block is called after all tasks are ran # Ensures the AppSignal agent has enough time to send the data to the AppSignal servers at_exit { sleep 10 } # Your script code ``` </CodeGroup> ### Monitor and stop helper <Warning> The `Appsignal.monitor_and_stop` helper is deprecated in favor of the [`enable_at_exit_hook` option](/ruby/configuration/options#option-enable_at_exit_hook), which ensures `Appsignal.stop` is called when the process exits, not whenever the `Appsignal.monitor_and_stop` helper is called. It's usage is described in the section above this one. Only use this helper in versions of the Ruby gem that do not support the [`enable_at_exit_hook` option](/ruby/configuration/options#option-enable_at_exit_hook). </Warning> If your process always runs one task/job and immediately exits afterward, you can use the `Appsignal.monitor_and_stop` helper. This will ensure that AppSignal stops automatically after the block has been executed. <CodeGroup> ```ruby Ruby theme={null} # This block is called right before the script exits # Ensures the AppSignal agent has enough time to send the data to the AppSignal servers at_exit do sleep 10 end class CronJobScript def call Appsignal.monitor_and_stop( :namespace => "cron", :action => "CronJobScript#call" ) do # Your code end end end ``` </CodeGroup> [integrations]: /ruby/integrations.html # Breadcrumbs Source: https://docs.appsignal.com/ruby/instrumentation/breadcrumbs <Tip> Breadcrumbs are available since Ruby gem version `2.11.2`. </Tip> Breadcrumbs where initially implemented in our [Front-end Javascript library](/front-end/breadcrumbs) with the idea that it would help debug an issue when you have a trail of breadcrumbs with (user) actions leading up to the error. We then realized this could also be useful for back-end requests, where you can add a time-ordered list of actions leading up to the error. For example adding breadcrumbs through decision trees that are otherwise not instrumented. <img alt="Breadcrumbs" /> ## Usage By default, no breadcrumbs are tracked, but it's really easy to track your own. Wherever an interesting event, operation or state change occurs in your app, you can leave a breadcrumb like so: <CodeGroup> ```ruby Ruby theme={null} Appsignal.add_breadcrumb("Navigation", "https://example.com", "", { :response => 200 }, Time.now.utc) Appsignal.add_breadcrumb("Network", "[GET] https://example.com", "", { :response => 500 }) Appsignal.add_breadcrumb("UI", "closed modal(change_password)", "User closed modal without actions") ``` </CodeGroup> Only the last 20 added breadcrumbs will be added to the current transaction. ## Breadcrumb Options | Option | Type | Description | | -------- | ------------------------ | ----------------------------------------------------------------------- | | category | String | Category to label the event under | | action | String | Contextual information related to the event | | message | String | (optional) A log message or other string to send to AppSignal | | metadata | `Object<String, String>` | (optional) An object of metadata related to the event | | time | Time object | (optional) Time object that responds to `.to_i`, defaults to `Time.utc` | # Custom markers Source: https://docs.appsignal.com/ruby/instrumentation/custom-markers [Custom markers](/application/markers/custom-markers) can be added to graphs and charts to mark important changes. They work similarly to Deploy markers, which let you know when a deployment was made. There are several ways to send [custom markers](/application/markers/custom-markers), through our UI, [API](/api/markers) and [public endpoint API](/api/public-endpoint/custom-markers). The Ruby gem also includes a helper class to create custom markers through our public endpoint. See the example below on how it can be used: <CodeGroup> ```ruby Ruby theme={null} Appsignal::CustomMarker.report( # The icon shown on the timeline :icon => "πŸŽ‰", # The message shown on hover :message => "Big event happened!", # Any time object or a string with a ISO8601 valid time is accepted :created_at => Time.now ) ``` </CodeGroup> You can call this helper anywhere in your application where an event occurs that needs to be tracked on the graph timeline, like Rake tasks. # Event formatters Source: https://docs.appsignal.com/ruby/instrumentation/event-formatters Event formatters are helpers classes to format event metadata for AppSignal transactions. In the AppSignal gem, event formatters are used to format event metadata from [ActiveSupport::Notifications instrumentation][as_instrumentation] events to AppSignal event metadata. When a block of code is instrumented by ActiveSupport::Notifications, AppSignal will record the event on the transactions, just like it would for the [`Appsignal.instrument` helper][instrument_helper]. Event formatters allow the data to be passed to the `ActiveSupport::Notifications.instrument` method call to be formatted for AppSignal events. The metadata for the events formatted by the event formatters will be visible on performance incidents detail pages in the event timeline. Hover over a specific event and the on mouse hover pop-up will show details like the exact database being queried or the query that was executed. <Tip> **Note**: If there are no other reasons to use [`ActiveSupport::Notifications`][as_instrumentation] instrumentation than AppSignal instrumentation, we recommend using the [`Appsignal.instrument` helper][instrument_helper] for instrumentation. Using `ActiveSupport::Notifications` adds more overhead than directly calling `AppSignal.instrument`. No event formatter will be needed either, as `AppSignal.instrument` accepts the metadata to be set directly. </Tip> ## Creating an event formatter An AppSignal event formatter is a class with one instance method, `format`. This format method receives the event payload Hash and needs to return an Array with three values. It's possible to add event formatter for libraries that use ActiveSupport::Notifications instrumentation, but look out that there's not already an event formatter registered for it. It's also possible to create an event formatter for your own events. When adding your own event names, please mind the [event naming](/api/event-names) guidelines. Each event formatter receives an event metadata "payload" Hash from which the event formatter can format the metadata for the event in AppSignal. This AppSignal event metadata needs to be returned by the event formatter in this order in an Array: <CodeGroup> ```ruby Ruby theme={null} def format(payload) [ "event title", "event body", Appsignal::EventFormatter::DEFAULT ] end ``` </CodeGroup> 1. An event title (`String`) * A more descriptive title of an event, such as `"Fetch current user"` or `"Fetch blog post comments"`. It will appear next to the event name in the event tree on the performance sample page to provide a little more context on what's happening. 2. An event body (`String`) * More details such as the database query that was used by the event. 3. An event body format (`Integer`) * Body format supports formatters to scrub the given data in the `body` argument to remove any sensitive data from the value. There are currently two supported values for the `body_format` argument. * `Appsignal::EventFormatter::DEFAULT` * This default value will indicate to AppSignal to leave the value intact and not scrub any data from it. * `Appsignal::EventFormatter::SQL_BODY_FORMAT` * The `SQL_BODY_FORMAT` value will indicate to AppSignal to run your data through the SQL sanitizer and scrub any values in SQL queries. <CodeGroup> ```sql SQL theme={null} -- An event body with the value of: SELECT * FROM users WHERE email = 'hector@appsignal.com' AND password = 'iamabot' -- becomes SELECT * FROM users WHERE email = ? AND password = ? ``` </CodeGroup> <Warning> **Warning**: the event formatter has no exception handling wrapped around it. If the custom event formatter raises an error, it will crash the web request or background job. </Warning> ## Example event formatter <CodeGroup> ```ruby Ruby theme={null} # A custom event formatter class class MyCustomEventFormatter def format(payload) [ payload[:title], payload[:body], Appsignal::EventFormatter::DEFAULT ] end end # Register the custom event formatter class for a specific event Appsignal::EventFormatter.register("event.custom", MyCustomEventFormatter) # Can be registerd multiple times for other event names Appsignal::EventFormatter.register("other_event.custom", MyCustomEventFormatter) ``` </CodeGroup> Then when instrumenting a block of code, use the event name that's registered for your custom event formatter. <CodeGroup> ```ruby Ruby theme={null} ActiveSupport::Notifications.instrument( "event.custom", # Use the registered event name { # Pass along event metadata :title => "some event name", :body => "some event body" } ) do sleep 2 end ``` </CodeGroup> ## Changes in gem 2.5 In AppSignal for Ruby gem version `2.5.2` some changes were made in how event formatters are registered. The old method of registering event formatters was deprecated in this release and will be removed in version `3.0` of the Ruby gem. The new method of registering EventFormatters will allow custom formatters to be registered after AppSignal has loaded. This allows EventFormatters to be registered in [Rails initializers](http://guides.rubyonrails.org/configuring.html#using-initializer-files). In gem version `2.5.1` and older, it is possible to register an event formatter like the following example, calling the `register` method in the class itself. <CodeGroup> ```ruby Ruby theme={null} # Pre 2.5.2 method of registering event formatters # This method is now deprecated class MyCustomEventFormatter < Appsignal::EventFormatter register "event.custom" def format(payload) [payload[:title], payload[:body], Appsignal::EventFormatter::DEFAULT] end end ``` </CodeGroup> With the new setup the register call was extracted from the class itself, so it can instead be registered directly on the EventFormatter class. <CodeGroup> ```ruby Ruby theme={null} class MyCustomEventFormatter def format(payload) [payload[:title], payload[:body], Appsignal::EventFormatter::DEFAULT] end end Appsignal::EventFormatter.register("event.custom", MyCustomEventFormatter) ``` </CodeGroup> This also means your EventFormatters no longer need to be a subclass of the `Appsignal::EventFormatter` class. [as_instrumentation]: /ruby/instrumentation/instrumentation.html#activesupport-notifications [instrument_helper]: /ruby/instrumentation/instrumentation.html#appsignal-instrumentation-helpers # Exception handling Source: https://docs.appsignal.com/ruby/instrumentation/exception-handling By default AppSignal tries to record as many exceptions (errors) as possible. With [our integrations](/ruby/integrations) for many frameworks and background job gems, not a lot of exceptions will slip past. In most cases, errors not caused by bugs in your code occur when your app interacts with the real world. Bots might drop by and try to post forms automatically; outdated links might direct visitors to content that doesn't exist anymore, and so on. To avoid these errors from being raised as problems in AppSignal, it's possible to add exception handling to your code or even let AppSignal entirely ignore specific errors. ## Ignore errors The AppSignal configuration makes it possible to [ignore errors](/guides/filter-data/ignore-errors). By providing a list of specific errors AppSignal will not send alerts when these errors are raised. ## Exception handling Simply ignoring an error will silence notifications, but could potentially hide a bigger problem. For this reason we recommend you add exception handling with `begin .. rescue` blocks to your application. Using `begin .. rescue` you can catch specific exceptions and add an alternative code path for when an exception occurs, such as rendering 404 pages or providing the user with more detailed error messages about what went wrong. <CodeGroup> ```ruby Ruby theme={null} begin user = Post.find(1) rescue RecordNotFound => e render :text => "Could not find post", :status => 404 end ``` </CodeGroup> There's a couple of scenarios that should be handled like this to provide proper HTTP responses when resources don't exist or when a form submission fails. Read our primer on [Exception handling](https://blog.appsignal.com/blog/2016/10/18/ruby-magic-exceptions-primer.html) for more information on how it works and how to implement it correctly. ### Rails rescue\_from Rails provides a mechanism to handle exceptions on controller-level. By defining a `rescue_from` statement for a specific error it's possible to create an alternative code path for when that exception is raised. Because this can be defined on any controller level this makes it possible to add application-level exception handling. <CodeGroup> ```ruby Ruby theme={null} class ApplicationController < ActionController::Base rescue_from ActiveRecord::RecordNotFound, :with => :record_not_found private def record_not_found render :text => "404: Resource not found", :status => 404 end end ``` </CodeGroup> More information about `rescue_from` can be found in the Rails guide about [ActionController](https://guides.rubyonrails.org/action_controller_overview.html#rescue-from). ### Handle 404s If a visitor hits a URL that cannot be handled by your routing or controller Rack and other frameworks will raise an exception. It's usually a good idea to handle these exceptions with a 404 response for your users. In controllers where a `find` operation is performed based on a parameter from an URL, it's recommended you handle `ActiveRecord::RecordNotFound` (or the equivalent in your ORM of choice) to show a 404 response as well. This can hide real bugs though, so it should be done with care. ### Handle invalid authenticity tokens Rails has a mechanism that protects your forms from being filled out by bots too easily. Any time a form is posted without a correct authenticity token a `ActionController::InvalidAuthenticityToken` will be raised. Sometimes legitimate users can run into these errors as well, so it's a good idea to have a separate error page explaining what went wrong. We advise to return this page with a 422 (Unprocessable Entity) response. ### Handle hacking attempts You might get errors because bots or hackers are trying to exploit security issues such as the notorious YAML exploit. Newer versions of Rails will throw a `Hash::DisallowedType` when this happens. A `RangeError` is also often a result of a hacking attempt. You could rescue these type of errors and return a 403 (Forbidden) response. ## Exception reporting helper methods AppSignal provides a single interface to report exceptions with [`Appsignal.report_error`](#appsignalreport_error). If your application is using Ruby gem version 3 or older, see the [legacy exception handling section](#legacy-exception-handling). ## Appsignal.report\_error <Compatibility /> Applications may have exception handling where they don't want to crash the Ruby process. By adding exception handling, the exception will no longer bubble up to the AppSignal instrumentation. AppSignal will not report these exceptions. If you want to report the exception without crashing the application, use the `Appsignal.report_error` helper to report it to AppSignal from within the exception handling. If an AppSignal Transaction is active, this helper will add the exception to the current Transaction. Applications can report multiple exceptions on one Transaction. If no Transaction is active, this helper will create a new Transaction and report the exception on the newly created Transaction. AppSignal will always report the exception this way when using `Appsignal.report_error`. <CodeGroup> ```ruby Ruby theme={null} begin # Some code that raises an exception rescue => error Appsignal.report_error(error) puts "Exiting. An error occurred: #{error}" exit 1 end ``` </CodeGroup> ### Adding metadata Customizing the metadata on the Transaction for the exception is possible by passing a block to the `Appsignal.report_error` helper. See our [Tagging](/guides/tagging) and [Data Customization](/guides/custom-data) guides for more information on what type of data can be added in this block. The metadata set in the `Appsignal.report_error`'s block only applies to the exception given to the helper. Metadata set outside the `Appsignal.report_error` blocks is added to all exceptions if there's an active transaction. <CodeGroup> ```ruby Ruby theme={null} begin # some code rescue => error Appsignal.report_error(error) do Appsignal.set_namespace("admin") Appsignal.set_action("MyCustomAction#perform") Appsignal.add_params(:param1 => "value1", :param2 => "value2") Appsignal.add_tags(:tag1 => "value1", :tag2 => "value2") Appsignal.add_custom_data( :i18n => { :locale => "en_GB", :default_locale => "en_US" } ) end end ``` </CodeGroup> ### Reporting multiple exceptions Multiple errors can be reported in one Transaction, like a Rails controller action handling an HTTP request or a Sidekiq background job. A maximum of 10 errors can be set on one Transaction. If multiple exceptions are reported in one Transaction, the metadata set in the `Appsignal.report_error`'s block only applies to the exception given to the helper. Metadata set outside of the `Appsignal.report_error` blocks is added to all exceptions. <CodeGroup> ```ruby Ruby theme={null} def index # This tag is added to all exceptions Appsignal.add_tags(:some_tag_for_all_errors => true) begin raise "something went wrong" rescue => error # Report the first exception Appsignal.report_error(error) do # This tag is only added to the first exception Appsignal.add_tags(:some_tag => true) end end begin raise "something else went wrong" rescue => error # Report the second exception Appsignal.report_error(error) do # This tag is only added to the second exception Appsignal.add_tags(:other_tag => true) end end # This tag is added to all exceptions Appsignal.add_tags(:another_tag_for_all_errors => true) end ``` </CodeGroup> ### Report exceptions that crash a process <Compatibility /> By default, AppSignal will report exceptions that crash a Ruby process as long as AppSignal is started before the exception occurs. <CodeGroup> ```ruby Ruby theme={null} # some_script.rb require "appsignal" Appsignal.start raise "I will crash the process!" ``` </CodeGroup> To disable this functionality, set the [`enable_at_exit_reporter` config option](/ruby/configuration/options#option-enable_at_exit_reporter) to `false`. ### Short-lived Ruby processes When reporting exceptions from [Ruby scripts](/ruby/instrumentation/background-jobs), [Rake tasks](/ruby/integrations/rake), Ruby processes that are short-lived, read the documentation on those pages on when to best call `Appsignal.stop` to ensure all exceptions are reported to AppSignal. ## Legacy exception handling Read this section when using AppSignal for Ruby gem version 3 or older. For newer versions of our Ruby gem, use the [`Appsignal.report_error` helper](#appsignalreport_error). AppSignal provides two exception reporting helper methods, which one you use will depend on the context of the error. The methods are: * **[`set_error`](#appsignal-set_error):** The `set_error` helper sets the error on the currently active Transaction. If no transaction is active, no error is reported. Setting an error on the currently active transaction overrides any error previously set on the transaction. * **[`send_error`](#appsignal-send_error):** Use `send_error` to report errors when no AppSignal transaction is active. ### Appsignal.set\_error <Compatibility /> There are scenarios where you have your own exception handling and don't want to crash the Ruby process. By adding your own exception handling the error is no longer bubbled up to the AppSignal integration and thus not recorded automatically. If you still want to track the error you can use `Appsignal.set_error` to add the exception to the current AppSignal Transaction. The error will be recorded in AppSignal, but your process will not crash. <CodeGroup> ```ruby Ruby theme={null} require "yaml" class SomeClass def call YAML.load(File.read("config.yml")) rescue SystemCallError => exception Appsignal.set_error(exception) puts "No config file found. Using defaults." end end ``` </CodeGroup> The exception will be tracked by AppSignal like any other error, and it allows you to provide custom error handling and fallbacks. Calling `set_error` only works when there is an AppSignal transaction active. Otherwise the error will be ignored. A transaction is active in most of our [automatically supported integrations](/ruby/integrations) and when using `Appsignal.monitor` or `Appsignal.monitor_transaction`. For more information on when to use `Appsignal.monitor_transaction`, see our [instrumentation for scripts and background jobs guide](/ruby/instrumentation/background-jobs). See [`Appsignal.send_error`](#appsignal-send_error) for sending errors without an AppSignal transaction. <CodeGroup> ```ruby Ruby theme={null} require "yaml" Appsignal.monitor :action => "My action" do begin YAML.load(File.read("config.yml")) rescue SystemCallError => exception Appsignal.set_error(exception) puts "No config file found. Using defaults." end end ``` </CodeGroup> ### Appsignal.send\_error <Compatibility /> AppSignal provides a mechanism to send errors to AppSignal without having to start a transaction. This is useful for tracking errors that occur in code that's not in a web or background job context, such as separate [Rake tasks](/ruby/integrations/rake) or [Ruby scripts](/ruby/instrumentation/background-jobs). This is useful for instrumentation that doesn't automatically create AppSignal transactions to profile, such as our [integrations](/ruby/integrations). You can use the `Appsignal.send_error` method to directly send an exception to AppSignal from any place in your code without starting an AppSignal transaction with `Appsignal.monitor` first. <CodeGroup> ```ruby Ruby theme={null} begin # some code rescue => e Appsignal.send_error(e) end ``` </CodeGroup> #### Adding metadata <Compatibility /> In AppSignal for Ruby gem 2.9 and newer an additional block can be passed to the `Appsignal.send_error` method to add more metadata to the error transaction. This includes metadata such as the action name and parameters. Older versions of the Ruby gem will not allow additional metadata to be set. <CodeGroup> ```ruby Ruby theme={null} begin # some code rescue => e Appsignal.send_error(e) do |transaction| transaction.set_action("my_action") transaction.set_namespace("my_namespace") transaction.params = { :time => Time.now.utc } end end ``` </CodeGroup> ### Appsignal.listen\_for\_error <Warning> This helper is removed in Ruby gem version 4. Instead, use a Ruby `rescue` block with the [`Appsignal.report_error` helper](#appsignalreport_error). </Warning> An alternative way to track errors with AppSignal is to wrap code that might raise an exception in a `listen_for_error` block. If an exception gets raised within that block it's automatically tracked by AppSignal and re-raised. This allows the application and frameworks to handle exception as normal. <CodeGroup> ```ruby Ruby theme={null} require "rake" require "appsignal" task :fail do Appsignal.listen_for_error do raise "I am an exception in a Rake task" end end ``` </CodeGroup> # Ignore instrumentation Source: https://docs.appsignal.com/ruby/instrumentation/ignore-instrumentation ## Ignore instrumentation events A web request or background job sample can contain many instrumentation events shown on the event timeline. However, not all events are essential as they may not provide significant or valuable insights into a sample's performance, and seeing a high number of events can make it difficult to spot problematic areas on the timeline. If the application has a place that creates a lot of events, like queries, external requests, or rendering views, the Ruby gem can ignore these events using the `ignore_instrumentation_events` helper. (In Ruby gem 3.10 and older the `ignore_instrumentation_events` helper is called `without_instrumentation`). <CodeGroup> ```ruby Ruby theme={null} class BackgroundWorker def perform Appsignal.ignore_instrumentation_events do 10_000.times do Appsignal.instrument "event_name.group_name" do # This instrumentation event will not be reported # Do complicated calculations end end end end end ``` </CodeGroup> The `ignore_instrumentation_events` helper will ignore events reported by the `instrument` helper. The Ruby gem will continue reporting errors and metrics that occur within this block. The `ignore_instrumentation_events` helper does not affect the sample's total duration. # Custom instrumentation for Ruby Source: https://docs.appsignal.com/ruby/instrumentation/instrumentation In order to find out what specific pieces of code are causing performance problems it's useful to add custom instrumentation to your application. This allows us to create better breakdowns of which code runs slowest and what type of action was the most time spent on. When you view saved samples of slow requests in AppSignal you'll be able to see all the instrumentation your application uses internally. Template rendering, ActiveRecord queries and caching are instrumented and will be shown in the sample. <img alt="Default event tree" /> That's already very useful, but wouldn't it be great if we could see measurements of specific pieces of code you suspect might influence your performance? Well, you can! By adding custom instrumentation we can create more detailed breakdowns of a request and background job. There are two ways of instrumenting your code. With AppSignal instrumentation helpers or with ActiveSupport Notifications instrumentation, as is used by Rails. <Tip> **Note**: Make sure you've [integrated AppSignal](/ruby/instrumentation/integrating-appsignal) before adding custom instrumentation to your application if it's not automatically integrated by one of our supported [integrations](/ruby/integrations). Follow our [instrumentation for scripts and background jobs guide](/ruby/instrumentation/background-jobs) for applications that we don't automatically instrument. </Tip> <Tip> **Note**: This page only describes how to add performance instrumentation to your code. To track errors please read our [exception handling](/ruby/instrumentation/exception-handling) guide. </Tip> ## Instrumentation helpers <Compatibility /> When you add custom instrumentation to your code you'll be able to receive even more insights into your application. For example, you have to work with an external API that fetches articles for your homepage: <CodeGroup> ```ruby Ruby theme={null} class ArticleFetcher def self.fetch(category) Appsignal.instrument('fetch.article_fetcher') do # Download and process the articles end end end ArticleFetcher.fetch('Latest news') ``` </CodeGroup> Once you add custom instruments like this AppSignal will start picking them up and will show you how much time both an event group (`article_fetcher` in this case) and individual events took. <img alt="Event tree with fetcher" /> In this case you'll notice that this API call is a huge influence on the performance of our homepage, which was hidden before. We might want to consider caching the articles. <Tip> **Note**: The name of the event you're instrumenting is important for our processor. Read more about [event naming](/api/event-names). </Tip> ### Nesting instrumentation You can use as many instruments in any combination you like. You can nest instrument calls and AppSignal will handle the nesting and aggregates of the measurements nicely. You just have to keep the final segment (after the last dot) of the key consistent. <CodeGroup> ```ruby Ruby theme={null} Appsignal.instrument('fetch.article_fetcher') do 10.times do Appsignal.instrument('fetch_single_article.article_fetcher') do # Fetch single article end end end ``` </CodeGroup> ### Collecting more data per event By default AppSignal will collect the duration of an event and send it to our servers. Since custom instrumentation is not hooked up to any framework internals you might need to pass along more data if you want event details to show up in AppSignal. This can be a descriptive title, or more specific information like the query from a database call. We already do this for ActiveRecord, Sequel, Redis, MongoDB, Sinatra, Grape, [and more](/ruby/integrations). There are two helpers to allow you to instrument your code with AppSignal. <CodeGroup> ```ruby Ruby theme={null} Appsignal.instrument(name, title = nil, body = nil, body_format = Appsignal::EventFormatter::DEFAULT, &block) # and Appsignal.instrument_sql(name, title = nil, body = nil, &block) ``` </CodeGroup> #### `name` argument The name of the event that will appear in the event tree in AppSignal. Read more about [event key naming](/api/event-names). #### `title` argument A more descriptive title of an event, such as `"Fetch current user"` or `"Fetch blog post comments"`. It will appear next to the event name in the event tree on the performance sample page to provide a little more context on what's happening. <CodeGroup> ```ruby Ruby theme={null} Appsignal.instrument('fetch.custom_database', 'Fetch current user') do # ... end ``` </CodeGroup> #### `body` argument More details such as a database query that was used by the event. <CodeGroup> ```ruby Ruby theme={null} sql = 'SELECT * FROM posts ORDER BY created_at DESC LIMIT 1' Appsignal.instrument('fetch.custom_database', 'Fetch latest post', sql) do # ... end ``` </CodeGroup> <Warning> **Warning**: Please make sure the body payloads are sanitized (sensitive/dynamic data is removed). Non-sanitized body events will be discarded if they reach a certain limit. </Warning> Good: <CodeGroup> ```ruby Ruby theme={null} Appsignal.instrument('custom.instrument', 'Instrument stuff', 'command/dynamic/?') do # ... end Appsignal.instrument('custom.instrument', 'Instrument stuff', 'command/dynamic/?') do # ... end ``` </CodeGroup> Bad: <CodeGroup> ```ruby Ruby theme={null} Appsignal.instrument('custom.instrument', 'Instrument stuff', 'command/dynamic/123') do # ... end Appsignal.instrument('custom.instrument', 'Instrument stuff', 'command/dynamic/234') do # ... end ``` </CodeGroup> When passing in an SQL query as the body, you can use `body_format = Appsignal::EventFormatter::SQL_BODY_FORMAT` to do so. #### `body_format` argument Body format supports formatters to scrub the given data in the `body` argument to remove any sensitive data from the value. There are currently two supported values for the `body_format` argument. ##### `Appsignal::EventFormatter::DEFAULT` value The `Appsignal::EventFormatter::DEFAULT` is the default value of this argument. By default AppSignal will leave the value intact and not scrub any data from it. ##### `Appsignal::EventFormatter::SQL_BODY_FORMAT` value The `Appsignal::EventFormatter::SQL_BODY_FORMAT` value will run your data through the SQL sanitizer and scrub any values in SQL queries. We recommend you use the `Appsignal.instrument_sql` helper for this instead. <CodeGroup> ```sql SQL theme={null} SELECT * FROM users WHERE email = 'hector@appsignal.com' AND password = 'iamabot' -- becomes SELECT * FROM users WHERE email = ? AND password = ? ``` </CodeGroup> ## ActiveSupport::Notifications <Tip> In older versions of the AppSignal gem (1.2 and lower) the `Appsignal.instrument` is not available. If you cannot upgrade, it's still possible to use `ActiveSupport::Notifications` instead. If you don't want to use the `Appsignal.instrument` helper, but instead want to use `ActiveSupport::Notifications`, you can still do so in AppSignal for Ruby gem 1.3 and higher too. </Tip> The method for instrumenting your code using `ActiveSupport::Notifications` is very similar to how AppSignal does it. Using the article fetcher example again you can see the differences are quite small. Also see our documentation on AppSignal [event formatters](/ruby/instrumentation/event-formatters) when using `ActiveSupport::Notifications`. For more information about ActiveSupport::Notifications instrumentation, see the official Rails [`ActiveSupport::Notifications` documentation](http://api.rubyonrails.org/classes/ActiveSupport/Notifications.html). <CodeGroup> ```ruby Ruby theme={null} require "active_support" class ArticleFetcher def self.fetch(category) ActiveSupport::Notifications.instrument("fetch.article_fetcher") do # Download and process the articles end end end ArticleFetcher.fetch("Latest news") ``` </CodeGroup> It works for nested instrumentation calls as well. <CodeGroup> ```ruby Ruby theme={null} require "active_support" ActiveSupport::Notifications.instrument("fetch.article_fetcher") do 10.times do ActiveSupport::Notifications.instrument("fetch_single_article.article_fetcher") do # Fetch single article end end end ``` </CodeGroup> `ActiveSupport::Notifications` is highly flexible, you can instrument your code any way you like. More information about `ActiveSupport::Notifications` can be found in the [Rails API docs](http://api.rubyonrails.org/classes/ActiveSupport/Notifications.html). <Warning> **Warning**: We do not track private `ActiveSupport::Notifications` events that start with an exclamation mark (`!`). These events mostly include private events generated by Rails. </Warning> # Integrating AppSignal in Ruby Source: https://docs.appsignal.com/ruby/instrumentation/integrating-appsignal It's possible that AppSignal does not provide automatic integration for your framework of choice, or maybe you're using your own application setup. See our [list of supported integrations](/ruby/integrations) to see what frameworks and gems we support with the AppSignal gem. When AppSignal does not support your application automatically, it's still possible to add AppSignal instrumentation. Our Ruby gem needs to be configured and started once at the beginning of a process. It can be [configured](/ruby/configuration) through a configuration file or by using environment variables. ## Configuration ### Environment variables When using [environment variables](/ruby/configuration/load-order#environment-variables) to configure AppSignal the gem will read the configuration from the environment once it starts. Calling `Appsignal.start` is enough. <CodeGroup> ```ruby Ruby theme={null} require "appsignal" # Load your app Appsignal.start ``` </CodeGroup> ### Configuration file When using a [configuration file](/ruby/configuration#ruby-configuration-file) to configure AppSignal, the Ruby gem needs to be configured before it is started. It will look for the `config/appsignal.rb` file in the current working directory of the application process. Alternatively, it can also be configured using the [`Appsignal.configure` helper](/ruby/configuration#appsignalconfigure-helper) as shown in the example below. <CodeGroup> ```ruby Ruby theme={null} require "appsignal" # Require the AppSignal gem # Optional: load integrations manually # These integrations need to be loaded before `Appsignal.configure` is called. # Appsignal.load(:sinatra) # Optional: Configure AppSignal via the configure helper # Appsignal.configure do |config| # # Some config # end # Lastly, start AppSignal Appsignal.start ``` </CodeGroup> AppSignal will look in the path of the first argument for a `config/` directory containing an `appsignal.rb` file to load the configuration. The second argument is the environment it will load from the configuration file. ## Next steps Continue with our [instrumentation for scripts and background jobs guide](/ruby/instrumentation/background-jobs) for applications that we don't automatically instrument. Use [instrumentation helpers](/ruby/instrumentation/instrumentation) to break down the instrumented code in more detail. # Add method instrumentation Source: https://docs.appsignal.com/ruby/instrumentation/method-instrumentation <Tip> <p>Notes:</p> <ul> <li> This feature is available since Ruby gem version 1.3 and only works for classes. </li> <li> Ruby 3.0 support for keyword arguments was added in Ruby gem `2.11.4`. </li> </ul> </Tip> Sometimes [instrumentation blocks](/ruby/instrumentation/instrumentation) are not accurate enough. Every application is different, and so is the code that runs it. Developers know what code and, more accurately, what methods to instrument. It's possible to instrument methods in your Ruby code directly with AppSignal. Using the `appsignal` Ruby gem you can use our object integrations which provides you with some useful helpers to do so. ## Installation Activate the object integration by requiring the following line after loading the appsignal gem itself <CodeGroup> ```ruby Ruby theme={null} require 'appsignal/integrations/object' ``` </CodeGroup> and proceed to specify which methods you want to test on any class you want. ### Example <CodeGroup> ```ruby Ruby theme={null} require 'appsignal' require 'appsignal/integrations/object' class Foo def bar 1 end appsignal_instrument_method :bar def self.bar 2 end appsignal_instrument_class_method :bar end Foo.new.bar # => 1 Foo.bar # => 2 ``` </CodeGroup> ## Usage We have different helpers for instance methods and class methods, `appsignal_instrument_method` and `appsignal_instrument_class_method` respectively. Call them on class level in any Ruby class, even those from the Ruby standard library, and start instrumenting. You don't need to include anything else in the class, once you load the integration file it becomes available everywhere. Instrument any method by calling the helper with the name of the method you want to instrument. If the method does not exist, it will throw an error, just like Ruby would do by default. Once a request has been processed by AppSignal with this type of instrumentation you will be able to see the method instrumentation in the event breakdown on the sample page. <img alt="Event tree with method instrumentation" /> You're also able to customize the name of the event that's send to us using the `:name` option. <CodeGroup> ```ruby Ruby theme={null} class Foo def bar end appsignal_instrument_method :bar def self.bar end appsignal_instrument_class_method :bar, name: "bar.class_method.Foo.methods" end ``` </CodeGroup> # Minutely probes Source: https://docs.appsignal.com/ruby/instrumentation/minutely-probes Minutely probes are a mechanism to periodically send [custom metrics](/metrics/custom) to AppSignal. This is a system that is included in the AppSignal Ruby gem by default. At the start of every minute the minutely probes are triggered one by one to collect metrics and then snoozed until the next minute. By default the AppSignal Ruby gem enables probes for [libraries](/ruby/integrations) that are detected for your app. <Tip> **Note**: In AppSignal Ruby gem 3.7.0 and lower, use the `Appsignal::Minutely.probes` module to register probes, rather than the new `Appsignal::Probes` API. </Tip> ## Usage The minutely probes allow the AppSignal Ruby gem to collect [custom metrics](/metrics/custom) by default for [integrations](/ruby/integrations) and app-specific metrics by [creating your own probe](#creating-probes). ### Multiple instances Once activated, the minutely probes system runs on every instance of an app. This means that if a probe report metrics without some kind of differentiating tag, global metrics may be overwritten by instance-level metrics. For example, there's a probe that tracks how large the local background job queue is for an app. The queue database runs locally on the instance and queue sizes may vary wildly. Each instance of an app reports different metric values for the same metric and tags, overwriting the metric value every minute with those of the last reporting instance. To remedy this, we suggest [tagging](/metrics/custom#metric-tags) your metrics with the hostname or something else unique for each instance. For example, the [Sidekiq probe](/ruby/integrations/sidekiq#minutely-probe) tags metrics with the Redis hostname by default. Alternatively you can [disable minutely probes](/ruby/configuration/options#option-enable_minutely_probes) for all but one instance, on which the minutely probes process is run. We suggest using the [`APPSIGNAL_ENABLE_MINUTELY_PROBES`](/ruby/configuration/options#option-enable_minutely_probes) environment variable to only enable it on the instance of your choosing. ## Configuration The minutely probes are configured using the [`enable_minutely_probes`](/ruby/configuration/options#option-enable_minutely_probes) config option. ## Creating probes If you want to track more [custom metrics](/metrics/custom) from your app than our the default probes that ship with our [integrations](/ruby/integrations/), you can add your own probe(s). An AppSignal minutely probe can be either of three things. Which of the three types to use for your class depends on the use case. * [Lambda probe](#lambda-probe) * [Class probe](#class-probe) * [Initialized class probe](#initialized-class-probe) ### Lambda probe The simplest probe type to register. If you have no dependencies for your probe this is the preferred method. <CodeGroup> ```ruby Ruby theme={null} # config/initializers/appsignal.rb or a file that's loaded on boot Appsignal::Probes.register(:my_probe, lambda do Appsignal.set_gauge("database_size", 10) end) ``` </CodeGroup> ### Class probe <Compatibility /> A class probe is a lazy initialized probe. It will only be started if the minutely probes are started. It will be initialized at the start of the minutely probes thread and remain initialized for as long as your app is running. This method is useful when you do not have [`enable_minutely_probes`](/ruby/configuration/options#option-enable_minutely_probes) enabled for every environment and don't want it to be initialized by default. <CodeGroup> ```ruby Ruby theme={null} # config/initializers/appsignal.rb or a file that's loaded on boot # Creating a probe using a Ruby class class BackgroundJobLibraryProbe def initialize # This is only called when the minutely probe gets initialized require "background_job_library" @connection = BackgroundJobLibrary.connection end def call stats = @connection.fetch_queue_stats Appsignal.set_gauge "background_job_library_queue_length", stats.queue_length Appsignal.set_gauge "background_job_library_processed_jobs", stats.processed_jobs end end # Registering a Class probe Appsignal::Probes.register( :background_job_library_probe, BackgroundJobLibraryProbe ) ``` </CodeGroup> ### Initialized class probe <Compatibility /> This method is most useful for [overriding default probes](#overriding-default-probes). The AppSignal Ruby gem ships some probes for [integrations](/ruby/integrations) by default. These default probes register probes as a [class](#class-probe) so they won't be initialized when overridden. When the probe default config does not fit your use case you can [override a default probe](#overriding-default-probes) with your own config. Note that we do not register a [class as a probe](#class-probe), but an instance of the class using `.new` and pass along a config object, e.g. `BackgroundJobLibraryProbe.new(<config>)`. <CodeGroup> ```ruby Ruby theme={null} # config/initializers/appsignal.rb or a file that's loaded on boot require "background_job_library" # Creating a probe using a Ruby class class BackgroundJobLibraryProbe def initialize(config) @connection = BackgroundJobLibrary.connection(config) end def call stats = @connection.fetch_queue_stats Appsignal.set_gauge "background_job_library_queue_length", stats.queue_length Appsignal.set_gauge "background_job_library_processed_jobs", stats.processed_jobs end end # Registering an initialized Class probe Appsignal::Probes.register( :background_job_library_probe, BackgroundJobLibraryProbe.new(:database => "redis://localhost:6379") ) ``` </CodeGroup> ## Registering probes <Compatibility /> Probes can be registered with the `register` method on the `Appsignal::Probes` module. This method accepts two arguments. * `key` - This is the key/name of the probe. This will be used to identify the probe in case an error occurs while executing the probe (which will be logged to the [appsignal.log file](/support/debugging#logs)) and to [override an existing probe](#overriding-default-probes). * `probe` - This is one of the [supported probe types](#creating-probes) that should be called every minute to collect metrics. <CodeGroup> ```ruby Ruby theme={null} # config/initializers/appsignal.rb or a file that's loaded on boot Appsignal::Probes.register(:my_probe, lambda do Appsignal.set_gauge("database_size", 10) end) ``` </CodeGroup> ### Rails apps We recommend registering your probes in a Rails initializer, like: `config/initializers/my_probe.rb`. ## Dependency requirements <Compatibility /> Not always should a probe be added to the list of probes by default. Some dependency may be required for the probe to work properly. This dependency check is used in probes shipped in the gem, but can also be used in your own probes. By adding a class method called `dependencies_present?`, a check can be performed ahead of starting the probe whether not it should be started. This works on both [class probes](#class-probe) and [initialized class probes](#initialized-class-probe). For the latter scenario there should be no call to said dependency in the `initialize` method of the probe as it's already initialized. <CodeGroup> ```ruby Ruby theme={null} # config/initializers/appsignal.rb or a file that's loaded on boot require "background_job_library" # Creating a probe using a Ruby class class BackgroundJobLibraryProbe def self.dependencies_present? # Only start the probe if the BackgroundJobLibrary version is higher or # equal to 1.0.0. Gem::Version.new(BackgroundJobLibrary::Version) >= Gem::Version.new("1.0.0") end def initialize(config = {}) @config = config end def call stats = connection.fetch_queue_stats Appsignal.set_gauge "background_job_library_queue_length", stats.queue_length Appsignal.set_gauge "background_job_library_processed_jobs", stats.processed_jobs end private def connection @connection ||= BackgroundJobLibrary.connection(@config) end end # Registering a Class probe with a `dependencies_present?` check Appsignal::Probes.register( :background_job_library_probe, BackgroundJobLibraryProbe ) # Also works for initialized probes Appsignal::Probes.register( :background_job_library_probe, BackgroundJobLibraryProbe.new(:url => "schema://my_connection_url:9090") ) ``` </CodeGroup> ## Overriding default probes AppSignal ships with default probes for certain [integrations](/ruby/integrations/). If for any reason this probe does not function properly or requires some additional configuration for your use case, you can override the default probe by [initializing the probe class](#initialized-class-probe) with your own config. Example overriding the [Sidekiq probe](/ruby/integrations/sidekiq#minutely-probe). <CodeGroup> ```ruby Ruby theme={null} # config/initializers/appsignal.rb or a file that's loaded on boot Appsignal::Probes.register( :sidekiq, # Use the same key as the default Sidekiq probe to override it Appsignal::Probes::SidekiqProbe.new(:hostname => ENV["REDIS_URL"]) ) ``` </CodeGroup> (Note that you'll need to set the `REDIS_URL` environment variable yourself.) Overriding probes will log a debug message in the [appsignal.log file](/support/debugging#logs) which can help to detect if a probe is correctly overridden. ## Unregister probes <Compatibility /> To unregister previously registered probes, including the default probes, use the `Appsignal::Probes.unregister` method. Call the unregister method with the name of the probe to unregister it. <CodeGroup> ```ruby Ruby theme={null} Appsignal::Probes.unregister( :probe_name # Use the same key as used in `Probes.register` to unregister it ) ``` </CodeGroup> # Track request queue time Source: https://docs.appsignal.com/ruby/instrumentation/request-queue-time ## Queue times A common setup for Ruby application is that the Ruby webserver such as Unicorn or Puma runs behind another (outer) webserver such as Nginx or Apache. Those are usually used to terminate SSL connections and handle static assets for example. When your Ruby webserver is busy processing requests, Nginx or Apache can still accept new connections and wait for a Ruby process to become available to handle the request. The outer webserver queue's the request in the meantime. Ideally there is enough capacity that the outer webserver never has to wait on Ruby, but in practice this can happen when there's a sudden spike of requests. A good indicator of capacity therefore is the queue time metric, e.g. the amount of time between when the outer webserver accepted the request and Ruby handles the request. A long queue time for a longer period of time indicates that you'll need to scale up the amount of Ruby processes/threads to handle requests, or scale more webservers. You can find the queue time metrics on the Performance graphs page: <img alt="Screenshot of Queue time graph" /> ## Setup AppSignal automatically tracks the queue time on Heroku, but if you run your own server with NGINX or Apache, you'll need to setup the correct headers for queue time tracking to work. ### NGINX You can use the [`${msec}`](http://nginx.org/en/docs/http/ngx_http_core_module.html#variables) variable with [NGINX 1.2.6](http://nginx.org/en/docs/http/ngx_http_core_module.html#variables) or higher. This is the current time in milliseconds. <CodeGroup> ```ruby Ruby theme={null} proxy_set_header X-Request-Start "t=${msec}"; ``` </CodeGroup> ### Apache In Apache [mod\_headers](https://httpd.apache.org/docs/current/mod/mod_headers.html) exposes a `"$t"` variable that can be used to track the queue time. Add the header as follows: <CodeGroup> ```ruby Ruby theme={null} RequestHeader set X-Request-Start "%t" ``` </CodeGroup> ### HAProxy Add the following to the relevant HAProxy frontend configuration to track the request's queue time. This exposes the datetime value for when the request was sent so that AppSignal can calculate the request's queue time. <CodeGroup> ```conf Config theme={null} http-request set-header X-Request-Start t=%[date(0, us)] ``` </CodeGroup> ## Namespaces From Ruby gem 2.11 and newer queue time is reported for all namespaces. Previously it would only report queue times for the "web" and "background" namespaces. Update to the latest version of the Ruby gem if you do not see queue time graphs for your [custom namespaces](/application/namespaces) # Ruby integrations Source: https://docs.appsignal.com/ruby/integrations AppSignal works with most popular Ruby frameworks and gems out-of-the-box such as: * [Active Job](/ruby/integrations/active-job) * [Capistrano](/ruby/integrations/capistrano) * [DataMapper](/ruby/integrations/datamapper) * [Delayed::Job](/ruby/integrations/delayed-job) * [Garbage Collection](/ruby/integrations/garbage-collection) * [Global VM Lock](/ruby/integrations/global-vm-lock) * [Grape](/ruby/integrations/grape) * [GraphQL](/ruby/integrations/graphql) * [Hanami](/ruby/integrations/hanami) * [HTTP.rb](/ruby/integrations/http) * [MongoDB](/ruby/integrations/mongodb) * [Multiple Rack libraries](/ruby/integrations/rack-libraries) * [Net::HTTP](/ruby/integrations/net-http) * [Padrino](/ruby/integrations/padrino) * [Puma](/ruby/integrations/puma) * [Que](/ruby/integrations/que) * [Rack](/ruby/integrations/rack) * [Rake](/ruby/integrations/rake) * [Redis](/ruby/integrations/redis) * [Resque](/ruby/integrations/resque) * [Ruby on Rails](/ruby/integrations/rails) * [Ruby VM](/ruby/integrations/ruby-vm) * [Sequel](/ruby/integrations/sequel) * [Shoryuken](/ruby/integrations/shoryuken) * [Sidekiq](/ruby/integrations/sidekiq) * [Solid Queue](/ruby/integrations/solidqueue) * [Sinatra](/ruby/integrations/sinatra) * [ViewComponent](/ruby/integrations/view-component) * [Webmachine](/ruby/integrations/webmachine) We try to make most integrations work automatically, but some might require some manual configuration steps. If a certain library isn't automatically supported it's possible to [integrate AppSignal manually][integrating]. For a more detailed examples on how to integrate AppSignal, visit our [examples repository][examples-repo]. [integrating]: /ruby/instrumentation/integrating-appsignal.html [examples-repo]: https://github.com/appsignal/appsignal-examples # Action Cable Source: https://docs.appsignal.com/ruby/integrations/action-cable <VersionRequirements /> [Action Cable](https://guides.rubyonrails.org/action_cable_overview.html) is Rails' framework for WebSocket connections, allowing real-time communication between the server and client. ## Supported instrumentation When you have Action Cable channels in your Rails application, AppSignal automatically tracks: * Channel subscription events * Channel messages * Error tracking in channels All Action Cable activity is reported under your application's "action\_cable" namespace. ## No additional configuration needed AppSignal supports Action Cable out-of-the-box without the need for manual instrumentation. For additional Rails setup instructions, see our [Rails integration guide](/ruby/integrations/rails). # Active Job Source: https://docs.appsignal.com/ruby/integrations/active-job <VersionRequirements /> Active Job is a framework for declaring jobs and making them run on a variety of queuing backends shipped with Rails. The Active Job integration tracks the execution and events from the job being performed. When AppSignal detects Active Job metrics, it will create an [Magic Dashboard](#magic-dashboard), allowing you to monitor core metrics visually. ## Supported adapters The Active Job integration supports all [Active Job adapters](https://api.rubyonrails.org/classes/ActiveJob/QueueAdapters.html). It may also offer support for adapters not listed on that page, which are accessible through a separate gem. However, please note that these adapters have not been tested. ## Integration with AppSignal-supported libraries The following background job libraries that AppSignal supports are automatically integrated with Active Job, allowing AppSignal to give you more in-depth performance insights: * [Delayed::Job](/ruby/integrations/delayed-job) * [Que](/ruby/integrations/que) * [Resque](/ruby/integrations/resque) * [Sidekiq](/ruby/integrations/sidekiq) * [Solid Queue](/ruby/integrations/solidqueue) ## Report errors on job discard <Compatibility /> Set the [`activejob_report_errors` config option](/ruby/configuration/options#option-activejob_report_errors) to `discard` to only report errors when a job is discarded. When a job is discarded, all job retries have been exhausted, and the job is no longer retried. Read the [Active Job documentation](https://guides.rubyonrails.org/active_job_basics.html#exceptions) to learn more about Active Job exception handling and failed job retries. <CodeGroup> ```ruby Ruby theme={null} class ExampleJob < ActiveJob::Base # Configure the retry attempts using the `retry_on` method retry_on StandardError, :attempts => 2 # ... end ``` </CodeGroup> <Warning> Some Active Job adapters (such as Sidekiq, Delayed::Job, etc.) have their own retry system. After Active Job has exhausted its retries, these libraries may trigger their own job retry system. This will retry jobs even after it has exhausted the Active Job retries and discarded the job. To avoid retrying jobs after Active Job has stopped retrying the job, and it reporting errors for those retries, make sure the adapter's retry system is disabled. When relying on Sidekiq's retry system, also configure it [to report errors only on discard](/ruby/integrations/sidekiq#report-errors-on-job-discard), so that it won't report errors multiple times. </Warning> ## Metadata AppSignal collects the following metadata for Active Job jobs: | Metadata | Description | | --------------- | -------------------------------------------------------------------------------- | | Active Job ID | The Active Job ID is reported by the Active Job adapter. | | Arguments | Arguments passed to the job when calling `perform_later`. | | Events | All `*.active_job` events. | | Job name | e.g. `MyBackgroundJob#perform` as used to group the job for AppSignal incidents. | | Priority | The sample's priority, if using an adapter that supports job priority. | | Provider job ID | The job ID reported by the Active Job adapter. | | Queue | The sample's queue name, if using an adapter that supports multiple queues. | | Queue time\* | Time elapsed from a job being queued and performed. | *\*From Rails version 6 onwards queue times are reported for the namespace they are reported from and can be viewed in AppSignal's [Performance Graphs](https://appsignal.com/redirect-to/app?to=performance/graphs).* AppSignal uses Active Job metadata to give you deeper contextual insights into job performance. When inspecting Active Job samples in AppSignal: * The Job name will be used to group the job for AppSignal incidents: <img alt="Example performance issues overview" /> * Metadata (excluding job name and events) will be available as filterable tags on incident samples: <img alt="Example Active Job tags" /> * `*.active_job` events will shown in the event timeline for performance samples: <img alt="Example Event timeline" /> ## Magic dashboard When AppSignal receives Active Job metrics, it will create an Active Job magic dashboard, available from the dashboard section of the AppSignal app. The Active Job magic dashboard will have the following graphs: | Graph | Metrics | [Tags](#tags) | | ------------------------------------------------------------------------------- | ---------------------------- | ---------------------------------------------------- | | [Duration per job class](#duration-per-job-class-graph) | `transaction_duration` | <li>`namespace`</li><li>`action`</li> | | [Job status per queue](#job-status-per-queue-graph) | `active_job_queue_job_count` | <li>`status`</li><li>`queue`</li> | | [Job status per queue with priority](#job-status-per-queue-with-priority-graph) | `active_job_queue_job_count` | <li>`status`</li><li>`queue`</li><li>`priority`</li> | | [Throughput per job class](#throughput-per-job-class-graph) | `transaction_duration` | <li>`namespace`</li><li>`action`</li> | Tags give you a contextual breakdown of Active job performance information, currently AppSignal reports the following tags for Active Job jobs: | Name | Description | | ---------- | ----------------------------------------------------------------------------------------------------------------- | | `action` | The name of the action the metric was reported from (eg: `YourWorker#perform`). | | `queue` | Named queue in which jobs are processed, e.g. `default` or `mailer`. | | `status` | Status of each job, either `processed` or `failed`. <br />Jobs that are `failed` are also counted as `processed`. | | `priority` | The priority given to each job, e.g. `0` or `1`. | Each tag will be represented with a colored line on the graph: <img alt="Example Actie Job dashboard" /> ### Duration per job class graph The Duration per job class graph shows the amount of time that it took for jobs to execute, grouped by the class that defines the job. You can use this graph to monitor the performance of jobs, per class, giving you a helicopter view of job performance and allowing you to quickly identify and investigate spikes in duration time. ### Job status per queue graph The Job status per queue with priority graph shows the number of jobs that were executed, grouped by their resulting status, by the queue in which they were enqueued. You can use this graph to monitor job error counts and performance based on queue, identify bottlenecks, and optimize your background jobs for scalability. ### Job status per queue with priority graph <Tip> Not all [Active Job adapters](#supported-adapters) support job priority. If jobs have no priority values, the graph will be empty. </Tip> The Job status per queue with a priority graph shows the number of jobs that were executed, grouped by their resulting status by the queue in which they were enqueued, and by the priority that was given to them. You can use this graph to monitor job error counts and performance based on queue and priority identify bottlenecks, and optimize your background jobs for scalability. ### Throughput per job class graph The Throughput per job class graph shows the amount of jobs that were executed, grouped by the class that defines the job. You can use this graph to monitor how many jobs are executed, grouped by the class that defines the job. # Capistrano Source: https://docs.appsignal.com/ruby/integrations/capistrano <VersionRequirements /> The [Capistrano](http://capistranorb.com/) integration makes sure an AppSignal deploy marker is created on every deploy. Read more about [deploy markers](/appsignal/terminology#markers). Some manual configuration may be required. ## Installation Make sure you load the `appsignal/capistrano` file in Capistrano's `Capfile`. This should be done automatically when you run the `appsignal install` command during installation. <CodeGroup> ```ruby Ruby theme={null} # Capfile require 'capistrano' # Other Capistrano requires. require 'appsignal/capistrano' ``` </CodeGroup> ## Configuration ### appsignal\_config <CodeGroup> ```ruby Ruby theme={null} # deploy.rb set :appsignal_config, name: 'My app' ``` </CodeGroup> `appsignal_config` allows you to override any config loaded from the [configuration file](/ruby/configuration). ### appsignal\_env (since gem version 1.3) <CodeGroup> ```ruby Ruby theme={null} # deploy.rb set :stage, :alpha set :appsignal_env, :staging ``` </CodeGroup> `appsignal_env` allows you to load a different AppSignal environment when a stage name doesn't match the AppSignal environment as named in the AppSignal config file or environment variable. ### appsignal\_revision (since gem version 0.8.8) <Warning> This method of reporting deploy markers is **deprecated** and may be removed at any time in the future. Reporting deploy markers using this method is only useful for small applications that use one application instance. It creates a new deploy marker at a specific time, regardless of the version the application is actually running. This also means it's also more error prone to group data that shouldn't belong to it under the deploy. We automatically detect deployment by reading the `REVISION` file which Capistrano adds to the release directory since Ruby gem 4.5.18. </Warning> In Capistrano 2 AppSignal is able to fetch the revision from the Capistrano config. In Capistrano 3 however, this is no longer available and setting the revision is recommended. <CodeGroup> ```ruby Ruby theme={null} # deploy.rb set :appsignal_revision, "my_revision" ``` </CodeGroup> The revision can be set manually or fetched from the git repository locally. <CodeGroup> ```ruby Ruby theme={null} # Sets the current branch's git commit SHA as the revision set :appsignal_revision, `git rev-parse --short HEAD`.strip ``` </CodeGroup> If you're using the branch configuration setting Capistrano you can also set git to fetch the commit SHA from the selected branch. <CodeGroup> ```ruby Ruby theme={null} set :branch, "main" # Sets the selected branch's git commit SHA as the revision set :appsignal_revision, `git rev-parse --short #{fetch(:branch)}`.strip ``` </CodeGroup> ### appsignal\_user (since gem version 2.4.0) Used in combination with `appsignal_revision` (if necessary), it's possible to customize a deploy user for Capistrano deploys. By default this uses the system's local username, read from the `USER` or `USERNAME` environment variable, so there's no need to configure it if the system has these variables available. If you do want to customize the deploy user, set the `:appsignal_user` config option in your Capistrano config. <CodeGroup> ```ruby Ruby theme={null} # deploy.rb set :appsignal_user, "Jane" # Custom deploy user name ``` </CodeGroup> ## Example applications We have two example applications in our examples repository on GitHub. The examples show how to set up AppSignal in small Capistrano applications while loading configuration values from the environment using gems like dotenv and Figaro. * [AppSignal + Capistrano + dotenv][example-dotenv-app] * [AppSignal + Capistrano + Figaro][example-figaro-app] [example-dotenv-app]: https://github.com/appsignal/appsignal-examples/tree/capistrano+dotenv [example-figaro-app]: https://github.com/appsignal/appsignal-examples/tree/capistrano+figaro # CodeOwnership Source: https://docs.appsignal.com/ruby/integrations/code-ownership <VersionRequirements /> The AppSignal gem is compatible out of the box with the [CodeOwnership](https://github.com/rubyatscale/code_ownership) gem. ## Usage When an error is reported, the AppSignal gem will tag the current transaction with the owner of the file that caused the error: <img alt="CodeOwnership integration in AppSignal" /> You can use this tag to filter samples in AppSignal. ## Disable integration CodeOwnership integration is enabled by default. To disable it, set the [`instrument_code_ownership` configuration option](/ruby/configuration/options#option-instrument_code_ownership) to `false`. # DataMapper Source: https://docs.appsignal.com/ruby/integrations/datamapper <VersionRequirements /> The AppSignal gem works out of the box with [DataMapper](http://datamapper.org/)! Nothing to do. Lucky! # Delayed::Job Source: https://docs.appsignal.com/ruby/integrations/delayed-job [Delayed::Job](https://github.com/collectiveidea/delayed_job) is created by the excellent folks at [Shopify](https://shopifyengineering.myshopify.com/) and one of the most popular background processors for Ruby and Rails. The AppSignal gem detects Delayed Job when it's present and hooks into the standard Delayed Job callbacks. No further action is required to enable integration. This integration aims to support all different Delayed::Job support enqueuing methods. Some methods may have some limitations and customization options. ## Classes with `#perform` methods <Tip> **Note**: Reporting of jobs using this method is supported since AppSignal Ruby gem version 2.11.0. </Tip> Delayed Job supports enqueuing jobs based on instances of classes or structs that listen to a `perform` instance method, when enqueued with `Delayed::Job.enqueue`. AppSignal will use the object's class name as the action naming, appending `#perform` to the action name. A job for `StructJob` is reported as `StructJob#perform`. <CodeGroup> ```ruby Ruby theme={null} class StructJob < Struct.new(:id) def perform # Do stuff end end Delayed::Job.enqueue(StructJob.new("id")) # Reported as "StructJob#perform" ``` </CodeGroup> Note that this method of enqueuing does not support arguments as a whole object is enqueued. Job objects are serialized when enqueued and deserialized when processed. AppSignal does not read the state of the deserialized object. The argument `id` for the `StructJob` in the example above is not reported. ## Jobs using `display_name` Delayed Job allows any class to define its own `display_name`. This `display_name` value can interfere with AppSignal's reporting if it is built using dynamic values, such as the arguments given to the job. If the `display_name` method return value does not return a String with the `ClassName#method_name` format, AppSignal treats each job as a separate entity, creating many Incidents and notifications. This breaks the grouping AppSignal does for these jobs, resulting in AppSignal reporting many unique variations of incidents for the job, and unusable metrics in graphs. To prevent this from happening, define an `appsignal_name` method that returns a job name using the `ClassName#method_name` format. This way the jobs will be grouped correctly again. <CodeGroup> ```ruby Ruby theme={null} class StructJobWithName < Struct.new(:id) def perform # Do stuff end # This returns an unique job name, creating new incidents and graphs for each # unique job name. def display_name "StructJobWithName-#{id}" end # This will group the jobs back to a single entity, allowing incidents # and graphs to work properly. def appsignal_name "StructJobWithName#perform" end end Delayed::Job.enqueue(StructJobWithName.new("id")) # Reported as "StructJobWithName#perform" ``` </CodeGroup> ## Delay method call support Method calls queued with the delay extension will be reported with an action name similar to how they are called. The arguments given to the delayed method will be reported as the arguments for the job. <CodeGroup> ```ruby Ruby theme={null} Post.delay.archive_all("some selector") # Reported as "Post.archive_all" Post.create(:title => "Post title").delay.send_mail("mail subject") # Reported as "Post#send_mail" ``` </CodeGroup> ## Delayed::Job.enqueue support <Tip> **Note**: Job name detection was added in Ruby gem version 2.11.0. </Tip> Custom jobs objects enqueued with `Delayed::Job.enqueue` will be reported as normal, but will not report arguments. A whole object is given to Delayed::Job, and serialized into YAML and back. We can't detect arguments in this scenario. <CodeGroup> ```ruby Ruby theme={null} Delayed::Job.enqueue job_object ``` </CodeGroup> ## Active Job support The Delayed Job integration is compatible with [Active Job](/ruby/integrations/active-job). It will report [queue times in graphs](https://appsignal.com/redirect-to/app?to=performance/graphs), queues and priorities if set on the job. Upgrade to version 2.11.0 of the Ruby gem or newer for improved support. ## Changes to the integration ### Queue time In AppSignal for Ruby gem 2.3.0 a change was made to the queue time registration. In [PR #297](https://github.com/appsignal/appsignal-ruby/pull/297) the start time of the job was used rather than the creation time of the job. This means that the time from when a job was created until the time it should start is no longer registered as queue time. This will prevent very long queue times from skewing the queue time graphs on AppSignal.com. ## Example applications Below is a list of example apps available to test the Delayed::Job integration with: * [AppSignal + Rails 5 + Delayed::Job](https://github.com/appsignal/appsignal-examples/tree/rails-5+delayed_job) * The example shows how to set up AppSignal with Delayed::Job and Rails. In the `README` file it lists all known and tested methods of enqueuing jobs that AppSignal supports. # Elasticsearch Source: https://docs.appsignal.com/ruby/integrations/elasticsearch The AppSignal gem works out of the box with [the official Elasticsearch gem for Rails](https://rubygems.org/gems/elasticsearch-rails). When an Elasticsearch query is performed in your Rails application, AppSignal will track it as an event. This event will be visible in the sample event timeline and slow queries features in the AppSignal interface. # Garbage Collection Source: https://docs.appsignal.com/ruby/integrations/garbage-collection <VersionRequirements /> The Ruby VM (Virtual Machine) uses Garbage Collection (GC) to prevent it from running out of process memory. Garbage Collection helps prevent your application from suffering memory outages due to running out of memory. This processes of cleaning up unused memory in Ruby apps can happen at any time. To get more insights into this you can use [Ruby's Garbage Collection profiler](https://ruby-doc.org/core/GC/Profiler.html). ## Profiler <Warning> We do not recommend enabling the Garbage Collection profiler in production environments, at least not for extended periods of time. The profiler's additional overhead may negatively impact your application's performance. </Warning> When the Ruby Garbage Collection profiler is enabled AppSignal will automatically collect metrics for its Ruby VM magic dashboard. The "GC time" graph will show how long the Ruby VM took to clean up the unused memory between measurements. This graph will spike if it suddenly has to process a lot more memory, such as after a high memory usage task or request for example. The GC profiler is disabled by default, so no metrics are reported in this graph. To enable the GC profiler, add the code shown below to your application. The profiler can be enabled at any time in the application, such as on boot or in preparation of memory intensive operations. Once the GC profiler is enabled, the "GC time" graph will start showing metrics after at least two minutes. This metric is reported by our [minutely probes](/ruby/instrumentation/minutely-probes) system and new measurements are made every minute. <CodeGroup> ```ruby Ruby theme={null} GC::Profiler.enable ``` </CodeGroup> To temporarily enable the GC profiler, make sure to disable the profiler afterwards. <CodeGroup> ```ruby Ruby theme={null} GC::Profiler.enable # Do memory intensive operation GC::Profiler.disable ``` </CodeGroup> For the Ruby gem to report any duration over zero for the garbage collection time, the profiler must be enabled for more than two minutes. This is the initial time the Ruby gem needs to measure the garbage collection time. We recommend enabling GC profiling for longer than the minimum of two minutes to ensure we have complete measurements required to compare and graph. # Global VM Lock Source: https://docs.appsignal.com/ruby/integrations/global-vm-lock <VersionRequirements /> The Ruby VM (Virtual Machine) schedules Ruby threads for execution. At any given point, only one thread at a time can be active and interact with the state of the Ruby VM. The mechanism by which the Ruby interpreter ensures this is the Global VM Lock (GVL). Switching between threads has an overhead of its own. The metrics on the Global VM Lock allow you to see the time a thread spends waiting for its turn to run, and the number of threads awaiting execution at a given time. These metrics can provide helpful insights for understanding performance issues in your application. When AppSignal detects Global VM Lock metrics, it will create an [Magic Dashboard](#magic-dashboard), allowing you to monitor core metrics visually. ## Installation <Warning> The `gvltools` library is only compatible with the official Ruby interpreter. JRuby is not supported. </Warning> For AppSignal to be able to obtain Global VM Lock metrics, you must add the `gvltools` library to your project: <CodeGroup> ```shell Shell theme={null} bundle add gvltools ``` </CodeGroup> Once installed, the AppSignal integration will automatically collect Global VM Lock metrics every minute. ## Magic dashboards Magic dashboards will appear in the [Dashboard](https://appsignal.com/redirect-to/app?to=dashboard) section of AppSignal. <img alt="Ruby GVL magic dashboard creation" /> The Global VM Lock magic dashboard has the following graphs: | Graph | Metric | | ----------------------------------------- | --------------------- | | [Global timer](#global-timer-graph) | `gvl_global_timer` | | [Waiting threads](#waiting-threads-graph) | `gvl_waiting_threads` | AppSignal reports the following tags for Global VM Lock metrics: | Name | Description | | -------------- | --------------------------------------------------------- | | `hostname` | The name of the host that the metric was reported from | | `process_id` | The ID of the process that the metric was reported from | | `process_name` | The name of the process that the metric was reported from | <Tip> The `process_id` and `process_name` tags are only reported when using AppSignal for Ruby version 3.9.3 or newer. </Tip> <img alt="Ruby GVL magic dashboard" /> ### Global timer graph The global timer graph shows the time that threads spent waiting to be resumed during the last minute, that is, waiting for their code to be executed again. #### Configuring global timer measurement Measuring the global timer has an estimated performance overhead of 5%. To prevent negative impacts on your application's performance, you may want to disable `gvl_global_timer` by default and enable it when needed for specific requests or thread-intensive jobs. To disable this metric at start time, set [the `enable_gvl_global_timer` configuration option](/ruby/configuration/options#option-enable_gvl_global_timer) to `false`. Then, you can use the `gvltools` library to enable and disable the global timer measurement without having to restart your application: <CodeGroup> ```ruby Ruby theme={null} require "gvltools" GVLTools::GlobalTimer.enable # some code that uses threads ... GVLTools::GlobalTimer.disable ``` </CodeGroup> ### Waiting threads graph The waiting threads graph shows the number of threads waiting to be resumed at any given time. The graph does not include threads that are not ready to be resumed, such as threads that are sleeping or awaiting an I/O event. To disable this metric, you can set [the `enable_gvl_waiting_threads` configuration option](/ruby/configuration/options#option-enable_gvl_waiting_threads) to `false`. # Grape Source: https://docs.appsignal.com/ruby/integrations/grape <VersionRequirements /> [Grape](https://www.ruby-grape.org/) applications are officially supported. Instrumenting Grape applications requires some manual setup. Follow the installation steps in AppSignal, starting by clicking 'Add app' on the [accounts screen](https://appsignal.com/accounts). <Note> Is your application using a combination of Rails, Grape, Hanami, Padrino or Sinatra? Follow our guide for [instrumenting multiple Rack applications](/ruby/integrations/rack-libraries). </Note> ## Installation <Tip> This installation guide is for Ruby gem 3.12 and newer. For applications using an older AppSignal for Ruby gem, follow our [legacy installation guide](#legacy-installation). </Tip> After [installing and configuring the AppSignal gem](/ruby/installation), add the AppSignal integration after the Grape app is loaded. The Grape integration is required from the AppSignal Ruby gem, and the event and instrumentation middlewares are added in the following code examples. <CodeGroup> ```ruby Ruby theme={null} # config.ru require "appsignal" # Add this require # Load the Grape integration Appsignal.load(:grape) # Add the AppSignal Rack event middleware # AppSignal for Ruby gem 4.7+ required use Appsignal::Rack::EventMiddleware # Require the app require_relative "api" # Start AppSignal Appsignal.start # Start the app run Acme::API ``` </CodeGroup> The next step is to add the AppSignal middleware to the application's base API class. It will report any unhandled exceptions from the application. <CodeGroup> ```ruby Ruby theme={null} # api.rb module Acme class API < Grape::API # Add this line insert_before Grape::Middleware::Error, Appsignal::Rack::GrapeMiddleware # Include this middleware # ... end end ``` </CodeGroup> ### Legacy installation Applications using AppSignal for Ruby gem 3.11 or older, follow these steps to install AppSignal in Grape applications. The Grape integration is required from the AppSignal Ruby gem, and the event handler and instrumentation middlewares are added in the following code examples. <CodeGroup> ```ruby Ruby theme={null} # config.ru require "appsignal/integrations/grape" # Add this require # Configure AppSignal Appsignal.config = Appsignal::Config.new( Dir.pwd, # The root of your app ENV["RACK_ENV"] # The environment of your app (development/production) ) # Start AppSignal Appsignal.start_logger # Not required in Ruby gem 3.9.3+ Appsignal.start # Add the AppSignal Rack EventHandler # AppSignal for Ruby gem 3.8+ required use ::Rack::Events, [Appsignal::Rack::EventHandler.new] # Require the app require_relative "api" # Start the app run Acme::API ``` </CodeGroup> The next step is to add the AppSignal middleware to the application's base API class. It will report any unhandled exceptions from the application. <CodeGroup> ```ruby Ruby theme={null} # api.rb module Acme class API < Grape::API # Add this line insert_before Grape::Middleware::Error, Appsignal::Grape::Middleware # Include this middleware # ... end end ``` </CodeGroup> ## Mounted Grape apps <Compatibility /> Mounting Grape applications on Ruby on Rails applications is supported. The Ruby gem needs to be a recent version to properly instrument requests for mounted Grape apps. ## Ignoring errors <Compatibility /> To ignore a specific Grape error, set the `grape.skip_appsignal_error` flag in the request environment. Setting this flag to `true` will instruct AppSignal not to report any errors during the request. Use this flag only if you need to dynamically ignore errors from a Grape application. Specify error classes in the [`ignore_errors` option](/guides/filter-data/ignore-errors) to ignore them for the entire application. For more information on muting notifications for specific errors see our [notification settings documentation](/application/notification-settings). <CodeGroup> ```ruby Ruby theme={null} get "/" do env["grape.skip_appsignal_error"] = true # Add this line to an endpoint or callback raise "uh oh" # Example error, don't copy this end ``` </CodeGroup> ## Reporting errors from `rescue_from` If an error is rescued in the app using `rescue_from,` AppSignal will not receive and track it. To still report the error, call `Appsignal.report_error` in the `rescue_from` block. (Use the `Appsignal.set_error` helper when using Ruby gem version 3 or older.) <CodeGroup> ```ruby Ruby theme={null} class Api < ::Grape::API insert_before Grape::Middleware::Error, Appsignal::Grape::Middleware format :json rescue_from :all do |error| Appsignal.report_error(error) error!({ :error => "error message" }.to_json, 500) end end ``` </CodeGroup> # GraphQL Source: https://docs.appsignal.com/ruby/integrations/graphql [GraphQL](https://graphql-ruby.org/) is the Ruby gem for GraphQL servers. AppSignal supports the GraphQL gem through the built-in instrumentation module in the GraphQL gem. ## Instrumentation To instrument your GraphQL app using AppSignal, load the AppSignal middleware in your schema. <CodeGroup> ```ruby Ruby theme={null} # TODO: Change the schema class to your schema class class MySchema < GraphQL::Schema trace_with(GraphQL::Tracing::AppsignalTrace) end ``` </CodeGroup> * Reference: [GraphQL AppSignal docs](https://graphql-ruby.org/queries/tracing.html#appsignal). ## Customize namespace and action You can AppSignal instrumentation helper methods to customize your instrumentation further. In the example below we group the requests by [namespace](/guides/namespaces) and action name: <CodeGroup> ```ruby Ruby theme={null} class GraphqlController < ApplicationController def create result = MySchema.execute(params[:query], :variables => params[:variables], :context => {}) render :json => result ensure # Customize the namespace Appsignal::Transaction.current.set_namespace("graphql") # Customize the action name based on the operationName, if any Appsignal::Transaction.current.set_action(params[:operationName] || "Unknown") end ``` </CodeGroup> # Hanami Source: https://docs.appsignal.com/ruby/integrations/hanami <VersionRequirements /> [Hanami](https://hanamirb.org/) are officially supported. Instrumenting Hanami applications requires some manual setup. Follow the installation steps in AppSignal, starting by clicking 'Add app' on the [accounts screen](https://appsignal.com/accounts). <Note> Is your application using a combination of Rails, Grape, Hanami, Padrino or Sinatra? Follow our guide for [instrumenting multiple Rack applications](/ruby/integrations/rack-libraries). </Note> <Tip> This page describes the integration for the Hanami framework, installed via the "hanami" gem. The Hanami::API framework (from the "hanami-api" gem) is not supported. </Tip> ## Installation After installing the AppSignal gem, add the AppSignal integration after requiring `hanami/boot` in the `config.ru` file. <CodeGroup> ```ruby Ruby theme={null} # config.ru require "appsignal" # Add this require require "hanami/boot" # Load the Hanami integration Appsignal.load(:hanami) # Start AppSignal Appsignal.start run Hanami.app # For Ruby gem 3.11 and older require "appsignal/integrations/hanami" # Add this line ``` </CodeGroup> ## Exception handling Hanami doesn't have any exception handling by default. The web server (like Puma or Unicorn) will show a basic "internal server error" page if an error occurs in the app. These unhandled exceptions will be reported to AppSignal automatically. The [Hanami exception handling guide](https://guides.hanamirb.org/v2.1/actions/exception-handling/) explains how to add custom exception handling to Hanami applications to render custom error pages. Handled exceptions will not be reported to AppSignal automatically. We recommend adding the following code to the application's base Action class found in `app/action.rb` to add exception handling for `StandardError`. This way, adding exception handling to every action class is unnecessary. In the `handle_standard_error` method, configured by `handle_exception`, call the `Appsignal.report_error` helper to report the exception to AppSignal and not miss any errors reported by your app. (Use the `Appsignal.set_error` helper when using Ruby gem version 3 or older.) <CodeGroup> ```ruby Ruby theme={null} # app/action.rb # auto_register: false # frozen_string_literal: true require "hanami/action" module MyHanamiApp class Action < Hanami::Action handle_exception StandardError => :handle_standard_error private def handle_standard_error(request, response, exception) # Report the error to AppSignal Appsignal.report_error(exception) # Render custom error page response.status = 500 response.body = "Sorry, something went wrong handling your request" end end end ``` </CodeGroup> After you add the `Appsignal.report_error` method to the Hanami exceptions you want to report, AppSignal will report these errors whenever they occur. # HTTP.rb gem Source: https://docs.appsignal.com/ruby/integrations/http <VersionRequirements /> The AppSignal gem works out of the box with [the HTTP.rb gem](https://github.com/httprb/http). Events for HTTP requests performed by your application using HTTP.rb will appear in the event timeline of your application's performance actions, as well as in the "Slow queries" performance panel. If you wish to disable our integration with the HTTP.rb gem, set the [`instrument_http_rb` config option](/ruby/configuration/options#option-instrument_http_rb) to false to disable it. # MongoDB instrumentation Source: https://docs.appsignal.com/ruby/integrations/mongodb <VersionRequirements /> The [Mongoid] gem relies on the [Mongo Ruby Driver]. AppSignal activates Mongo Ruby Driver instrumentation automatically if it is detected in the project. AppSignal's MongoDB instrumentation supports the [Mongo Ruby Driver] gem and the [Mongoid] gem out-of-the-box; no manual setup is required. When AppSignal detects MongoDB metrics, it will create an [Magic Dashboard](#magic-dashboard), allowing you to monitor core metrics visually. ## Performance monitoring Once AppSignal begins reporting MongoDB metrics, AppSignal will give you performance insights via: * [Event timeline](#event-timeline) * [Sample breakdown](#sample-breakdown) * [Slow queries](#slow-queries) ### Event timeline The event timeline gives you deep insights into MongoDB query performance, allowing you to see exactly what queries are run, when, and what impact they're having on your application's responsiveness. <img alt="Example MongoDB event timeline" /> ### Sample breakdown Sample breakdowns allow you to review MongoDB performance at a glance, allowing you to quickly spot performance problems without having to dive deep into the details. <img alt="Example MongoDB performance sample" /> ### Slow queries AppSignal has a whole suite of tools aimed at helping you improve your application's performance. Slow queries is a simple and informative overview of your application's slow queries and the impact they're having on your application's performance, allowing you to quickly and confidently decide on the steps needed to optimize them. <img alt="Example of AppSignal slow queries feature" /> ## Magic dashboard When AppSignal receives MongoDB metrics, it will create a MongoDB magic dashboard, available from the dashboard section of the AppSignal app. The MongoDB magic dashboard will have the following graphs: | Graph | Metrics | Tags | | --------------------------------------- | ------------------------ | ---------- | | [Throughput](#throughput-graph) | `mongodb_query_duration` | `database` | | [Query duration](#query-duration-graph) | `mongodb_query_duration` | `database` | Tags give you a contextual breakdown of Active job performance information currently AppSignal reports the following tags for Active Job jobs: | Name | Description | | ---------- | ---------------------------------------------- | | `database` | Name of database metric data is recorded from. | Each tag will be represented with a colored line on the graph: <img alt="Example MongoDB dashboard" /> ### Throughput graph The Throughput graph shows the amount of queries executed on each MongoDB database. You can use this graph to understand how many queries your app's databases are handling, spot inefficient queries, and potential n+1 and scaling problems. ### Query duration graph The Query duration graph shows the 95th percentile and average duration of the queries executed on each MongoDB database. You can use this graph to understand the performance of database queries, pinpoint performance issues, and fine-tune slow queries. [Mongoid]: https://github.com/mongodb/mongoid [Mongo Ruby Driver]: https://github.com/mongodb/mongo-ruby-driver # Net::HTTP Source: https://docs.appsignal.com/ruby/integrations/net-http The AppSignal gem works out of the box with the built-in Net::HTTP module. Events for HTTP requests performed by your application using Net::HTTP will appear in the event timeline of your application's performance actions, as well as in the "Slow queries" performance panel. # Ownership Source: https://docs.appsignal.com/ruby/integrations/ownership <VersionRequirements /> The AppSignal gem is compatible out of the box with the [Ownership](https://github.com/ankane/ownership/) gem. ## Usage When using the Ownership gem to assign ownership to specific blocks of code, the AppSignal for Ruby gem will automatically add an owner tag to the resulting sample, with the last owner that was assigned to a block of code during that sample as the tag's value: <CodeGroup> ```ruby Ruby theme={null} # This will set the owner tag for this sample to :growth owner :growth do crunch_user_numbers end ``` </CodeGroup> <img alt="Ownership integration in AppSignal" /> You can use this tag to filter samples in AppSignal by the team that owns the corresponding code. When an error is reported, the owner tag for the error sample will be set to the owner of the block of code that caused the error. ## Setting namespaces You can also set the [`ownership_set_namespace` configuration option](/ruby/configuration/options#option-ownership_set_namespace`) to `true` in order to, alongside the owner tag, have the namespace be automatically set to the owner. Using namespaces allows you to easily see which performance actions and errors are owned by a specific team. Note that changing the namespace for actions and errors that have already been reported to AppSignal will cause them to be reported as new actions and errors. ## Disable integration To disable the integration with the Ownership gem entirely, set the [`instrument_ownership` configuration option](/ruby/configuration/options#option-instrument_ownership) to `false`. # Padrino Source: https://docs.appsignal.com/ruby/integrations/padrino [Padrino](http://www.padrinorb.com/) applications are officially supported. Instrumenting Padrino applications requires some manual setup. Follow the installation steps in AppSignal, starting by clicking 'Add app' on the [accounts screen](https://appsignal.com/accounts). <Note> Is your application using a combination of Rails, Grape, Hanami, Padrino or Sinatra? Follow our guide for [instrumenting multiple Rack applications](/ruby/integrations/rack-libraries). </Note> ## Installation After installing the AppSignal gem, add the AppSignal integration after requiring `padrino`. <CodeGroup> ```ruby Ruby theme={null} # config/boot.rb require "rubygems" unless defined?(Gem) require "bundler/setup" require "appsignal" # Add this require # Load the Padrino integration Appsignal.load(:padrino) # Start AppSignal Appsignal.start # For Ruby gem 3.11 and older require "appsignal/integrations/padrino" # Add this line ``` </CodeGroup> Then, create the AppSignal configuration file. For more details on configuring AppSignal, see the [Ruby configuration](/ruby/configuration) page. After these steps, start your Sinatra app and wait for data to arrive in AppSignal. # Puma Source: https://docs.appsignal.com/ruby/integrations/puma <VersionRequirements /> [Puma](http://puma.io/) was built for speed and parallelism. Puma is a small library providing a fast and concurrent HTTP 1.1 server for Ruby web applications. The AppSignal Ruby gem automatically inserts a listener into the Puma server; no manual setup is required. ## Puma metrics plugin The AppSignal Puma plugin will [collect metrics about how Puma is operating](#metrics). When AppSignal detects Puma metrics, it will create an [Magic Dashboard](#magic-dashboard), allowing you to monitor core metrics visually. To enable the metrics collection, add the AppSignal plugin to your Puma configuration: <CodeGroup> ```ruby Ruby theme={null} # puma.rb (or config/puma.rb) plugin :appsignal ``` </CodeGroup> <Tip> The StatsD server bundled with the AppSignal Agent must be active for the Puma metrics plugin to work. Make sure [the `enable_statsd` config option](/ruby/configuration/options#option-enable_statsd) is not set to `false`. </Tip> Puma may require additional configuration to load your application's [secrets](#configuration-secrets), which may be necessary for AppSignal to start. ## Usage with `prune_bundler` If your `puma.rb` file includes `prune_bundler`, you must add AppSignal as a runtime dependency. <Tip> To use Puma with `prune_bundler`, Puma version 4.2.0 or higher is required. </Tip> <CodeGroup> ```ruby Ruby theme={null} # puma.rb (or config/puma.rb) prune_bundler plugin :appsignal extra_runtime_dependencies ["appsignal"] ``` </CodeGroup> ## Usage with `preload_app!` If your `puma.rb` file includes `preload_app!`, some configuration is required to correctly report metrics from [minutely probes](/ruby/instrumentation/minutely-probes). When `preload_app!` is true, the minutely probes are run in the Puma primary process. In the primary process, the probes cannot access the same data that the app running in Puma workers can, reporting inaccurate or no data. In the Puma `puma.rb` config file, stop the AppSignal minutely probes in the `before_fork` callback to stop the minutely probes in the Puma main process. Then, start the minutely probes in the worker process from the `on_worker_boot` callback. <CodeGroup> ```ruby Ruby theme={null} # puma.rb or config/puma.rb # When preload_app! is set preload_app! # Add this before_fork callback to stop the minutely probes in the Puma main process before_fork do Appsignal::Probes.stop end # Add this on_worker_boot callback to start the minutely probes in the Puma worker processes on_worker_boot do Appsignal::Probes.start end ``` </CodeGroup> ## Secrets If you use a library such as [Rails](https://guides.rubyonrails.org/security.html#custom-credentials) or [dotenv](https://github.com/bkeepers/dotenv) to manage your app's secrets and configure AppSignal, you will need to load these in your Puma configuration. AppSignal runs a background process in Puma's main process when using the Puma plugin. The rest of your app is not loaded by default in Puma's main process (unless you use `preload_app!`, which may not be suitable for your app). Without additional configuration, the AppSignal config will fail to load, and AppSignal will not start. No "on boot" hook is available in Puma to load your extra config in the main process. To load your configuration, add it to the root of your `puma.rb` configuration file, as in the example below. <CodeGroup> ```ruby Ruby theme={null} # puma.rb (or config/puma.rb) plugin :appsignal # Add this plugin # Rails secrets # Add this line when using Rails secrets in your `config/appsignal.rb` or `config/appsignal.yml` file. require "rails" # Add this section when using dotenv for secrets management require "dotenv" Dotenv.load # or for Rails apps: require "dotenv/load" Dotenv.load # Rest of your Puma config... ``` </CodeGroup> ### Hostname This probe listens to the [`APPSIGNAL_HOSTNAME` config option from the environment variable](/ruby/configuration/options#option-hostname) for the hostname tag added to all its metrics. If none is set, it will try to detect it automatically. Use the `APPSIGNAL_HOSTNAME` system environment variable to set the hostname if you want to change the detected hostname. ### StatsD port This probe listens to the [`APPSIGNAL_STATSD_PORT` config option from the environment variable](/ruby/configuration/options#option-statsd_port) for the configuration of non-default StatsD ports. If the environment variable is not set, it defaults to 8125. For the Puma main process, it is required to use the environment variable; it will not read the AppSignal file configuration. ## Phased restart Puma [phased restarts](https://github.com/puma/puma/blob/master/docs/restart.md) don't restart the main Puma process, meaning that the AppSignal background process does not get restarted either on a phased restart. If you have made changes to the AppSignal config, you will need to fully restart your Puma app afterward to have the configuration change take effect. <CodeGroup> ```sh Shell theme={null} # After changing the AppSignal config, restart using: pumactl restart # instead of: pumactl phased-restart ``` </CodeGroup> ## Magic dashboard When AppSignal receives Puma metrics, it will create a Puma magic dashboard, available from the dashboard section of the AppSignal app. The Puma magic dashboard will have the following graphs: | Graph | Metrics | Tags | | ----------------------------------------------- | ------------------------- | ----------------------------------------------- | | [Connection backlog](#connection-backlog-graph) | `puma_connection_backlog` | `hostname` | | [Pool capacity](#pool-capacity-graph) | `puma_pool_capacity` | `hostname` | | [Threads](#threads-graph) | `puma_threads` | <li>`max`</li><li>`running`</li> | | [Worker info](#worker-info-graph) | `puma_workers` | <li>`booted`</li><li>`count`</li><li>`old`</li> | Tags give you a contextual breakdown of Active job performance information. AppSignal reports the following tags for Active Job jobs: | Name | Description | | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | | `booted` | Total number of currently booted workers for this server. | | `count` | Number of currently running threads for this server. | | `hostname` | Name of the host the metric was reported from. | | `max` | Maximum number of configured threads for this server. | | `old` | Number of workers running the previous configuration/code of the server at the moment in time. Puma will phase these out as new workers start. | | `running` | Number of currently running threads for this server | Graphs allow you to monitor your application's metrics visually. You can add markers to graphs and click on any data point to gain insights into your application's state at that time. <img alt="Example Puma magic dashboard" /> ### Connection backlog graph The Connection backlog graph shows the amount of incoming connections to the server that are waiting to be served in the server's backlog queue. You can use the Connection backlog graph to monitor how many requests are waiting to be handled and spot Puma bottlenecks. ### Pool capacity graph The Pool capacity graph shows the amount of Puma threads available to receive requests, including Puma threads that have yet to be spawned. You can use the Pool capacity graph to monitor the availability of Puma threads and optimize workers. ### Threads graph The Threads graph shows information about the threads spawned by Puma to serve web requests aggregated across all Puma workers. To serve web requests, Puma will spawn more threads when needed. The graph will show you the amount of threads running against the max available number of threads. You can use the Threads graph to monitor the demand and supply of Puma threads and optimize workers. ### Worker info graph The Worker info graph shows how many Puma workers are working and what version of your website they are using. The count line shows how many workers are working in total, while the booted and old lines show how many workers are using the new version and how many workers are using the old version of your application. You can use the worker info graph to monitor the status and performance of your Puma workers and see how many workers are running on an outdated configuration of your application. [thread pool]: https://github.com/puma/puma/#thread-pool [clustered mode]: https://github.com/puma/puma/#clustered-mode # Que Source: https://docs.appsignal.com/ruby/integrations/que <VersionRequirements /> [Que](https://github.com/chanks/que/) is a high-performance alternative to DelayedJob or QueueClassic that improves the reliability of your application by protecting your jobs with the same ACID guarantees as the rest of your data. If Que is detected when AppSignal starts, we automatically hook into Que to track exceptions and performance issues. Job names are automatically detected based on the Que worker class name and are suffixed with the `run` method name, resulting in something like: `MyWorker#run`. You can recognize events from Que with the name `perform_job.que` in the event timeline on the performance incident detail page. ## Active Job support The Que integration is compatible with [Active Job](/ruby/integrations/active-job). Upgrade to version 2.11.0 of the Ruby gem or newer for improved support. ## Example application We have an example application in our examples repository on GitHub. * [AppSignal + Rails 5 + Que][example-app] The example shows how to set up a Rails 5 app with Que monitored by AppSignal. [example-app]: https://github.com/appsignal/appsignal-examples/tree/rails-5+que # Rack Source: https://docs.appsignal.com/ruby/integrations/rack To instrument Rack applications, AppSignal provides a Rack instrumentation middleware. If you use any of the supported Rack frameworks like [Rails], [Sinatra], [Hanami], [Grape], or [Padrino], we recommend using those instrumentations instead. ## Add the instrumentation middleware <Compatibility /> <Tip> Using an older AppSignal Ruby gem? Follow [our legacy guide](#using-the-legacy-instrumentation-middleware). </Tip> To [integrate AppSignal][integrate] in a Rack application, we first need to load, [configure][configuration], and start AppSignal. Then, instrument the Rack app by adding our Rack `EventMiddleware` and `InstrumentationMiddleware` to the middleware stack. This documentation explains how to do this in your application's `config.ru` file. <CodeGroup> ```ruby Ruby theme={null} # config.ru require "appsignal" # Load AppSignal Appsignal.start # Start the AppSignal integration # Add the Rack EventMiddleware first use Appsignal::Rack::EventMiddleware # Add the Rack InstrumentationMiddleware use Appsignal::Rack::InstrumentationMiddleware # Load your app with a require statement here, like require_relative "app" # Add other middleware here if needed # Finally, run the app use MyApp.run ``` </CodeGroup> Ensure the `EventMiddleware` and `InstrumentationMiddleware` are registered in the application middleware stack as early as possible. The earlier these middleware are registered, the more request runtime the middleware will instrument. If other middleware are registered beforehand, our middleware will not instrument these other middleware. After adding the `EventMiddleware` and `InstrumentationMiddleware` to your app's middleware stack, [the action](#setting-the-action-name) needs to be set for each route in your app in AppSignal. Without an action name to group requests, the event middleware will not report request information. For more insights into the operation of your Rack application, we recommend [adding additional instrumentation][instrumentation] to the application's endpoints. ### The Rack event middleware We recommend adding our Rack event middleware to all Rack applications. This middleware will ensure we track The AppSignal Rack event middleware has the following features: * Instrumentation of the request and recording a `process_request.rack` event. * Reporting Exceptions that occur in the app and middleware. * Tracking the response status code as the `response_status` tag on the sample. * Tracking the response status code as the `response_status` metric, with the `namespace` and `status` tags. ### The Rack instrumentation middleware We recommend that in addition to the `Appsignal::Rack::EventMiddleware`, the `AppSignal::Rack::InstrumentationMiddleware` is added to the app. This middleware supplements the event middleware's instrumentation by adding tags for the request path and request method, as well as tracking response body handling and response body closing operations. The instrumentation middleware has the following features: * Instrumentation of the request and recording a `process_request.rack` event. * Reporting Exceptions that occur in the app. * Tracking the request path and request method as tags on the sample. * Instrumentation of the response body handling and recording a `process_response_body.rack` event for this operation. * Instrumentation of the response body closing and recording a `close_response_body.rack` event for this operation. ## Using the legacy instrumentation middleware <Compatibility /> <Warning> The GenericInstrumentation middleware was deprecated in Ruby gem 3.10.0. Please use the [new guide](#add-the-instrumentation-middleware) instead. </Warning> To [integrate AppSignal][integrate] in a Rack application, we first need to load, [configure][configuration], and start AppSignal. Then, instrument the Rack app by adding our Rack `GenericInstrumentation` middleware to the middleware stack. This documentation explains how to do this in your application's `config.ru` file. <CodeGroup> ```ruby Ruby theme={null} # config.ru # Load and configure AppSignal require "appsignal" # Load AppSignal Appsignal.config = Appsignal::Config.new( File.expand_path("../", __FILE__), # Application root path ENV["RACK_ENV"], # Application environment ) Appsignal.start # Start the AppSignal integration Appsignal.start_logger # Start logger # Load your app with a require statement here, like require_relative "app" # Add the GenericInstrumentation middleware use Appsignal::Rack::GenericInstrumentation # Add other middleware here if needed # Finally, run the app use MyApp.run ``` </CodeGroup> Ensure the `EventMiddleware` and `InstrumentationMiddleware` are registered in the application middleware stack as early as possible. The earlier these middleware are registered, the more request runtime the middleware will instrument. If other middleware are registered beforehand, our middleware will not instrument these other middleware. After adding the `EventMiddleware` and `InstrumentationMiddleware` to your app's middleware stack, [the action](#setting-the-action-name) needs to be set for each route in your app in AppSignal. Without an action name to group requests, the event middleware will not report request information. For more insights into the operation of your Rack application, we recommend [adding additional instrumentation][instrumentation] to the application's endpoints. ## Setting the action name Set an action name on the AppSignal transaction for a request so we can group endpoints in our issues and metrics. We recommend using a static action name per endpoint, like `GET /blog`, `POST /users`, `PUT /users/:id`, etc. To set an action name for a request, call the `Appsignal.set_action` helper from the app. <Warning> Do not use the request path of the route as the action name if the path has dynamic segments. Using real request paths for action names breaks our request grouping by creating unique issues for each possible request path. </Warning> <CodeGroup> ```ruby Ruby theme={null} # app.rb require "rack" # Example pure-Rack app class MyApp def call(env) case [env["REQUEST_METHOD"], env["PATH_INFO"]] when ["GET", "/"] Appsignal.set_action("GET /") # Action name set here body = <<~BODY <h1>Rack example app</h1> <ul> <li><a href="/slow">Slow request</a></li> <li><a href="/error">Error request</a></li> </ul> BODY [200, {"Content-Type" => "text/html"}, [body]] when ["GET", "/slow"] Appsignal.set_action("GET /slow") # Action name set here sleep 1 [200, {"Content-Type" => "text/plain"}, ["Slow response"]] when ["GET", "/error"] Appsignal.set_action("GET /error") # Action name set here raise "uh oh" else Appsignal.set_action("NotFound") # Action name set here [404, {"Content-Type" => "text/plain"}, ["Page not found"]] end end end ``` </CodeGroup> [configuration]: /ruby/configuration [integrate]: /ruby/instrumentation/integrating-appsignal.html [instrumentation]: /ruby/instrumentation/instrumentation.html [Rails]: /ruby/integrations/rails.html [Sinatra]: /ruby/integrations/sinatra.html [Hanami]: /ruby/integrations/hanami.html [Grape]: /ruby/integrations/grape.html [Padrino]: /ruby/integrations/padrino.html # Multiple Rack libraries Source: https://docs.appsignal.com/ruby/integrations/rack-libraries <VersionRequirements /> If an application uses multiple Ruby web frameworks, like the ones listed below, follow this guide to set up instrumentation for all libraries. * [Grape](/ruby/integrations/grape) * [Hanami](/ruby/integrations/hanami) * [Padrino](/ruby/integrations/padrino) * [Sinatra](/ruby/integrations/sinatra) * [Rails](/ruby/integrations/rails), no `Appsignal.load` required for Rails. ## Installation For each library AppSignal should integrate with, call `Appsignal.load(:library_name)` where `:library_name` is replaced with the library name you want to instrument. Follow the guides listed above for each library for additional steps per library and guidance on where to position each `Appsignal.load` call. <CodeGroup> ```ruby Ruby theme={null} require "appsignal" Appsignal.load(:grape) Appsignal.load(:hanami) Appsignal.load(:padrino) Appsignal.load(:sinatra) Appsignal.start ``` </CodeGroup> ## Rack example app For example, in an application that uses a lot of these Rack libraries: <CodeGroup> ```ruby Ruby theme={null} # config.ru require "appsignal" Appsignal.load(:grape) require_relative "./app" Appsignal.load(:hanami) Appsignal.load(:padrino) Appsignal.load(:sinatra) Appsignal.start run MyApp.run ``` </CodeGroup> ## Rails app example In a Rails app, add the loaders to the `config/application.rb` file. <CodeGroup> ```ruby Ruby theme={null} # config/application.rb require_relative "boot" require "rails/all" Bundler.require(*Rails.groups) Appsignal.load(:sinatra) # ... ``` </CodeGroup> # Ruby on Rails Source: https://docs.appsignal.com/ruby/integrations/rails [Ruby on Rails](http://rubyonrails.org/) is supported out-of-the-box by AppSignal. To install follow the installation steps in AppSignal, start by clicking 'Add app' on the [accounts screen](https://appsignal.com/accounts). The AppSignal integration for Rails works by tracking exceptions and performance in requests. When an error occurs in a controller during a request AppSignal will report it. Performance issues will be based on the duration of a request and create a timeline of events detailing which parts of the application took the longest. ## Active Job <Compatibility /> See our [Active Job page](/ruby/integrations/active-job) for more information on how our Active Job instrumentation works. ## Action Cable <Compatibility /> See our [Action Cable page](/ruby/integrations/action-cable) for more information on how our Action Cable instrumentation works. ## Configure AppSignal in an initializer <Compatibility /> We recommend using our [`config/appsignal.rb` config file](/ruby/configuration/load-order#appsignal-rb-config-file) or [environment variables](/ruby/configuration/load-order#5-environment-variables) to [configure AppSignal](/ruby/configuration). By default, it's not possible to configure AppSignal from a Rails initializer, because AppSignal loads before your application's initializers, in order to be able to report errors that take place during initialization. To configure AppSignal in a Rails initializer, first configure Rails to start AppSignal after the app's initializers have run. <CodeGroup> ```ruby Ruby theme={null} # config/application.rb # ... module MyApp class Application < Rails::Application # Add this line config.appsignal.start_at = :after_initialize # Other config end end ``` </CodeGroup> Then, in the initializer: <CodeGroup> ```ruby Ruby theme={null} # config/initializers/appsignal.rb Appsignal.configure do |config| config.ignore_actions = ["My action"] end ``` </CodeGroup> Do not call `Appsignal.start` in the initializers. The Ruby gem will start AppSignal automatically when Rails has run all initializers. When a Rails app is configured to start AppSignal after the initializers have loaded, it is no longer possible to [report errors from initializers when booting Rails app](#error-reporting-from-initializers). ## Error reporting from initializers By default, AppSignal reports errors that occur in controller, Rake tasks and Active Job jobs. It does not report errors that occur when the application is booting, before the Rails initializers. To do get notified when these errors occur, adding the following to your `config.ru` file, around the line that requires the `environment.rb` file. <CodeGroup> ```ruby Ruby theme={null} # config.ru begin require ::File.expand_path("../config/environment", __FILE__) rescue Exception => error Appsignal.send_error(error) raise end ``` </CodeGroup> The errors that occur here will not be grouped under an incident with an action name. ## Backtrace cleaner With the Rails integration, AppSignal will run the backtrace of each exception through the [Rails backtrace cleaner][backtrace cleaner docs]. This cleaner gives you the option to modify or filter out unwanted backtrace lines, removing clutter and noise from the backtrace. You can add or remove filters and silencers to the default configuration. **Filters** will mutate the given line. An example would be to remove the `Rails.root` prefix. **Silencers** will remove the line from the backtrace, if the given expression returns `true`. You can add these additional backtrace cleaner rules in an initialize. For example: <CodeGroup> ```ruby Ruby theme={null} # config/initializers/backtrace_cleaner.rb bc = Rails.backtrace_cleaner bc.add_filter { |line| line.gsub(Rails.root.to_s, '<root>') } bc.add_silencer { |line| line.index('<root>').nil? and line.index('/') == 0 } bc.add_silencer { |line| line.index('<root>/vendor/') == 0 } ``` </CodeGroup> For more information about the backtrace cleaner, see the [Rails BacktraceCleaner documentation][backtrace cleaner docs]. ## Error reporter <Compatibility /> AppSignal reports errors raised via `ActiveSupport::ErrorReporter` by default. `ActiveSupport::ErrorReporter` was introduced in Rails 7.0 to standardize custom error reporting. You can disable this functionality with the [`enable_rails_error_reporter`](/ruby/configuration/options#option-enable_rails_error_reporter) configuration option. If a transaction is active in the context an error is reported through the Rails error reporter, it will include the same metadata and sample data as the active transaction: namespace, action name, tags, custom data, parameters, etc. <CodeGroup> ```ruby Ruby theme={null} # In both scenarios, the error is reported by AppSignal Rails.error.handle do raise "some error" end Rails.error.record do raise "some error" end ``` </CodeGroup> <Warning> In AppSignal for Ruby gem version 3, some behavior was different. Please consult the [Ruby gem 3 legacy behavior](#ruby-gem-3-legacy-behavior) section for more information about the differences. </Warning> ### Namespace and action from the current transaction When reporting errors, we determine the namespace and action name in which it takes place, such as a controller or background job, on a best-effort basis. The incident namespace and action name will not always be set or be accurate. If an AppSignal transaction is active (like in a web request or background job) the error reported with `Rails.error.handle/record` will have the same namespace, action name, tags, parameters, custom data, etc. as the active transaction. If no AppSignal transaction is active, no namespace, action name, tags, etc. will be set by default. ### Namespace and action from the context If you want to change the reported error's namespace and action name without changing them on the already active AppSignal transaction, you can customize this on the error reporter call. <CodeGroup> ```ruby Ruby theme={null} # The error reported here will have the "custom_namespace" namespace # and "CustomizedActionName#index" action name Rails.error.handle(:context => { :appsignal => { :namespace => "custom_namespace", :action => "CustomizedActionName#index" } }) do raise "some error" end ``` </CodeGroup> ### Tags from the active transaction By default, the request/job's transaction tags are copied to the error reporter's error AppSignal transaction from the request/job's transaction. <CodeGroup> ```ruby Ruby theme={null} # Rails controller example using a before_action callback class ExamplesController < ApplicationController before_action do Appsignal.add_tags(:tag1 => "value1", :tag2 => "value2") end def index # The error reported here will have the same tags set # as in the `before_action` callback Rails.error.handle do raise "some error" end end end ``` </CodeGroup> ### Tags from context You can add tags to a reported error by using `context` in the `Rails.error.handle/record` call. These tags will only be set on the error reported with the `Rails.error.handle/record` methods. <CodeGroup> ```ruby Ruby theme={null} Rails.error.handle(:context => { :tag1 => "value1", :tag2 => "value2" }) do raise "some error" end ``` </CodeGroup> The same tagging limitations apply as for using [`Appsignal.add_tags`](/guides/tagging#ruby). ### Ruby gem 3 legacy behavior In AppSignal for Ruby gem version 3 the error reporting behavior is different. * Errors reported with the `Rails.error.handle` method are reported to AppSignal. * Errors reported with `Rails.error.record` are not reported to AppSignal to avoid reporting the error twice when it's being reported by our Rails error reporting middleware. All errors reported with the Rails error reporter are reported as separate errors. They do not always include the same metadata and sample data from any active AppSignal transaction. See the section for [context inheritance limitations](#context-inheritance-limitations) for more information. <CodeGroup> ```ruby Ruby theme={null} # Reported by AppSignal Rails.error.handle do raise "some error" end # NOT reported by AppSignal Rails.error.record do raise "some error" end ``` </CodeGroup> #### Context inheritance limitations In Ruby gem 3 the context inheritance from the active transaction is limited. The metadata and some of the sample data is only copied if it set at the time `Rails.error.handle/record` is called. In practice this mean Rails controllers and Active Job jobs will be accurately reported. Other libraries like Sidekiq jobs, no action name is set when reporting errors with `Rails.error.handle`. Tags set after `Rails.error.handle/record` is called are not reported for the error reported using this helper. ## Runners <Compatibility /> AppSignal will automatically report errors inside [Rails runners](https://guides.rubyonrails.org/command_line.html#bin-rails-runner). Some manual setup is also required to instrument a runner's performance. We recommend putting the runner's code in a separate file and wrap it in the [`Appsignal.monitor` helper](/ruby/instrumentation/background-jobs), as shown in the example below. ```bash Bash theme={null} bin/rails runner path_to_file.rb ``` <CodeGroup> ```ruby Ruby theme={null} Appsignal.monitor(:namespace => :runner, :action => "Runner name") do # Some code end ``` </CodeGroup> If your Rails runner runs on a container that is only started to run this task, make sure that [`enable_at_exit_hook` option](/ruby/configuration/options#option-enable_at_exit_hook) is set to `true` (which should be the default on containers). This will ensure the data gets flushed to the AppSignal agent before the runner shuts down. [backtrace cleaner docs]: https://api.rubyonrails.org/classes/ActiveSupport/BacktraceCleaner.html [error reporter]: https://guides.rubyonrails.org/error_reporting.html # Rake task monitoring Source: https://docs.appsignal.com/ruby/integrations/rake <VersionRequirements /> Every exception recorded in a [Rake][rake] task will be sent to AppSignal and filed under the "Background" [namespace](/application/namespaces). Note that we only track exceptions in Rake tasks. There is no performance monitoring for Rake tasks. (To manually integrate performance monitoring in select Rake tasks please see our [integration guide][integration] and [custom instrumentation guide][custom-instrumentation].) Depending on what version of the AppSignal gem you use and in what context some manual steps are required. ## Integrations ### Rails applications For Rails applications make sure you depend on the `:environment` task. This loads the Rails application into memory and starts AppSignal as part of the application. <CodeGroup> ```ruby Ruby theme={null} # lib/tasks/my_task.rb task :my_task => :environment do # do stuff end ``` </CodeGroup> #### Rakefile Your Rails application's `Rakefile` should look something like the example below. This should already be the case, no need to change it. <CodeGroup> ```ruby Ruby theme={null} # Rakefile require File.expand_path("../config/application", __FILE__) # Only require this file for gem version < 1.0 # require "appsignal/integrations/rake" Rails.application.load_tasks ``` </CodeGroup> (For older versions of the AppSignal gem, versions `< 1`, you will need to require the Rake integration manually. It is automatically loaded for version `1.x` and higher.) ### Ruby applications For pure Ruby applications some extra steps are required to load AppSignal. AppSignal needs to be required, configured and loaded. See also our [integration guide][integration]. <CodeGroup> ```ruby Ruby theme={null} # Rakefile require "appsignal" Appsignal.start task :foo do raise "bar" end ``` </CodeGroup> ## Monitoring Rake task performance <Compatibility /> To monitor Rake task performance and all events that occur in the task, configure AppSignal with the [`enable_rake_performance_instrumentation` config option](/ruby/configuration/options#option-enable_rake_performance_instrumentation) set to `true`. With this feature enabled, all Rake tasks will instrumented and counted towards your plan. ## Stop requirement <Compatibility /> For Rake tasks running on short-lived hosts, it is required to stop the AppSignal Ruby gem before the Rake process exits. This will ensure it reports the data from the Rake tasks to AppSignal before the host shuts down. This behavior is only needed in such scenarios like: * When a scheduled Rake task (a cron job) is run by a hosting service. * When a Rake task is run on a container that starts to run this Rake task and shuts down when the Rake task exits. * When a Rake task is run on a Heroku runner, or similar hosting providers. It is not needed to stop the AppSignal Ruby gem if the host on which the script is started, continues to run after the script has exited. AppSignal is stopped automatically when the Rake task exits and a container or hosting environment like Heroku is detected. This behavior is controlled by the [`enable_at_exit_hook` option](/ruby/configuration/options#option-enable_at_exit_hook). Ensure this option is set to true for scripts that require AppSignal to be stopped, if it's not automatically detected. It may be needed to add an additional `sleep` call of a couple seconds to ensure there's enough time to send all the data. Use the `at_exit` usage example from the code below if needed. <CodeGroup> ```ruby Rakefile theme={null} # Short-lived host example task # This block is called after all tasks are ran # Ensures the AppSignal agent has enough time to send the data to the AppSignal servers at_exit { sleep 10 } task :foo do # Your Rake task code end ``` </CodeGroup> ### Stop requirement legacy <Warning> The section below is for applications using Ruby gem 4.5.7 and lower. These versions do not include the [`enable_at_exit_hook` option](/ruby/configuration/options#option-enable_at_exit_hook) which automates this behavior. For newer versions of the Ruby gem, see the [stop requirement section](#stop-requirement). </Warning> When running a single Rake task on a short-lived host (e.g. with Docker containers, Kubernetes or Heroku schedulers) there are three requirements. This guarantees that the app's AppSignal extension has time to flush the data to the agent and the agent has time to send the data to our API before shutting (the container) down. **The requirements are:** * `Appsignal.stop` must be called in the Rake task. * When [Rake task performance monitoring](#monitoring-rake-task-performance) is enabled, this is done automatically for all tasks. * [`running_in_container`](/ruby/configuration/options#option-running_in_container) must be set to true in the config. * For most containers types `running_in_container` is automatically set to true when detected, for others manual configuration is required. * A sleep of e.g. 10 seconds to give AppSignal agent time to sent the data An example of how `Appsignal.stop` is called in the Rakefile: <CodeGroup> ```ruby Rakefile theme={null} # Short-lived host example task # This block is called after all tasks are ran # The argument "rake" is the name of the parent process name which is being # stopped and logs it as the reason why AppSignal is stopping. at_exit do Appsignal.stop "rake" sleep 10 # For short-lived hosts, give the AppSignal agent time to send the data end task :foo do # Tracking data with AppSignal in your task Appsignal.increment_counter "my_custom_counter" end ``` </CodeGroup> **Note**: A sleep of 10 seconds was added to the end of the Rake task example in the example above. This is required for tasks that are run on short-lived hosts. When the task completes, the process stops. The `Appsignal.stop` call flushes all the transaction data currently in the AppSignal extension to our agent. It then sleeps for 10 seconds to allow the agent to send the data before shutting down. [rake]: https://github.com/ruby/rake [integration]: /ruby/instrumentation/integrating-appsignal.html [custom-instrumentation]: /ruby/instrumentation/instrumentation.html # Redis gem Source: https://docs.appsignal.com/ruby/integrations/redis <VersionRequirements /> The AppSignal gem works out of the box with the [`redis`](https://rubygems.org/gems/redis/) and [`redis-client`](https://rubygems.org/gems/redis-client) Ruby gems. Events for Redis queries performed by your application will appear in the event timeline of your application's performance actions, as well as in the "Slow queries" performance panel. If you wish to disable our integration with the Redis gem, set the [`instrument_redis` config option](/ruby/configuration/options#option-instrument_http_rb) to `false` to disable it. # Resque Source: https://docs.appsignal.com/ruby/integrations/resque <VersionRequirements /> [Resque](https://github.com/resque/resque) is a Redis-backed Ruby library for creating background jobs, placing them on multiple queues, and processing them later. ## Active Job support The Resque integration is compatible with [Active Job](/ruby/integrations/active-job). Upgrade to version 2.11.0 of the Ruby gem or newer for improved support. ## Example apps We've added a Rails 5 + Resque [example app](https://github.com/appsignal/appsignal-examples/tree/rails-5+resque) to our [examples repository](https://github.com/appsignal/appsignal-examples). Please take a look if you're having trouble getting AppSignal for Resque configured. # Ruby VM Source: https://docs.appsignal.com/ruby/integrations/ruby-vm <VersionRequirements /> The Ruby VM (Virtual Machine) schedules Ruby threads for execution. At any given point, only one thread at a time can interact with the state of the Ruby VM. AppSignal supports Ruby VM out of the box. When AppSignal detects Ruby VM metrics, it will create an [Magic Dashboard](#magic-dashboard), allowing you to monitor core metrics visually. ## Magic dashboards Magic dashboards will appear in the dashboard section of the AppSignal app. <img alt="Ruby VM magic dashboard creation" /> The Ruby VM magic dashboard will have the following graphs: | Graph | Metrics | Tags | | ----------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------ | | [Allocated objects](#allocated-objects-graph) | `allocated_objects` | `hostname` | | [Garbage Collection Count](#garbage-collection-count-graph) | <li>`minor_gc_count`</li> <li>`minor_gc_count`</li> <li>`gc_count`</li> | <li>`metric`</li><li>`hostname`</li> | | [Heap slots](#heap-slots-graph) | <li>`heap_live`</li> <li>`heap_free`</li> | <li>`metric`</li><li>`hostname`</li> | | [Ruby VM](#ruby-vm-graph) | <li>`class_serial`</li><li>`global_constant_state`</li><li>`constant_cache_invalidations`</li><li> `constant_cache_misses`</li> | <li>`metric`</li><li>`hostname`</li> | | [Thread count](#thread-count-graph) | `thread_count` | `hostname` | Tags give you a contextual breakdown of Ruby VM performance information. AppSignal reports the following tags for Ruby VM performance: | Name | Description | | ---------- | -------------------------------------------------- | | `hostname` | The name of the host the metric was reported from. | | `metric` | The total metric value for all hosts. | AppSignal will represent each tag with a colored line on the graph: <img alt="Ruby VM magic dashboard example graph" /> ### Allocated objects graph The Allocated objects graph shows how many complex Ruby values (objects, not strings, integers, booleans, etc.) are using memory in the Ruby virtual machine. You can use the Allocated objects graph to monitor and optimize your application's memory usage and performance. ### Garbage collection count graph The GC counts graph shows the amount of garbage collection events/runs during the last minute, split between major and minor events. You can use the GC counts graph to monitor the frequency of garbage collection and its impact on your application’s performance and memory usage. ### Heap slots graph The Heap slots graph shows the heap slots currently allocated by the Ruby virtual machine, split between live and free slots. You can use the Heap slots graph to monitor memory allocation and identify the potential causes of memory leaks or fragmentation. ### Ruby VM graph <Warning> The metrics `constant_cache_misses` and `constant_cache_invalidations` are only available in Ruby versions 3.2.0 and higher. </Warning> The Ruby VM graph shows statistics from the RubyVM.stat method about the constant cache and the classes created in your application. You can use the Ruby VM graph to monitor the cache status of constant values and how your application affects the Ruby VM state. ### Thread count graph The Thread count graph shows the number of threads currently executing in your application. You can use the Thread count graph to monitor your application's threading. Ruby VM Lock runs serially, meaning it can only execute one thread at a time. A high thread count may lead to performance problems. # Sequel Source: https://docs.appsignal.com/ruby/integrations/sequel The [Sequel][sequel] gem is a fast ORM for Ruby. AppSignal supports Sequel automatically and no manual instrumentation is needed. ## Disable instrumentation We have a configuration option to disable instrumentation for Sequel. Read more about [`:instrument_sequel`][instrument-sequel]. ## Known issues ### sequel-rails integration When using the [sequel-rails][sequel-rails] gem the instrumentation from the sequel-rails gem and AppSignal gem can [conflict when running migrations][instrumentation-issue]. Because both gems are instrumenting sequel you'll get two instrumentation events and possible an error. [Disable the AppSignal sequel instrumentation](#disable-instrumentation) is this occurs. ### Lack of instrumentation Some Sequel extensions override the AppSignal Ruby gem instrumentation. One such extension is the [error\_sql][error_sql-extension]. This causes AppSignal to be unable to instrument Sequel. The effect being no Sequel instrumentation events to appear on AppSignal.com. To use the AppSignal instrumentations in this scenario, the AppSignal Sequel instrumentation needs to be loaded manually after all other extensions have loaded. <CodeGroup> ```ruby Ruby theme={null} # Load extension that overrides the AppSignal instrumentation. This is an # example. Other extensions might override it too. Sequel::Database.extension :error_sql # Manually load the instrumentation of sequel with AppSignal in combination # with an extension that overrides the AppSignal gem instrumentation on load. # # Make sure you set `instrument_sequel` to `false` in the AppSignal config. # http://docs.appsignal.com/ruby/configuration/ # # Note: Use `Appsignal::Hooks::SequelLogExtension` for Sequel version 4.34 # and below. Sequel::Database.register_extension( :appsignal_integration, Appsignal::Hooks::SequelLogConnectionExtension ) Sequel::Database.extension(:appsignal_integration) ``` </CodeGroup> Note: only since version `2.0.2` do the other extension's functionality remain intact after loading the AppSignal instrumentation. ## Example applications We have two example applications in our examples repository on GitHub. * [AppSignal + Sequel][example-app]\ The example shows how to set up AppSignal with Sequel and Rails, without ActiveRecord and using only the sequel gem, not the sequel-rails gem. * [AppSignal + Sequel - manual instrumentation app][example-manual-instrumentation-app]\ This example shows how to manually load the AppSignal Sequel instrumentation in a Rails application, using only the sequel gem, not the sequel-rails gem. [sequel]: http://sequel.jeremyevans.net/ [sequel-rails]: https://github.com/TalentBox/sequel-rails [instrument-sequel]: /ruby/configuration/options.html#option-instrument_sequel [instrumentation-issue]: https://github.com/appsignal/appsignal-ruby/issues/91 [example-app]: https://github.com/appsignal/appsignal-examples/tree/rails-5+sequel [example-manual-instrumentation-app]: https://github.com/appsignal/appsignal-examples/tree/rails-5+sequel-manual-instrumentation [error_sql-extension]: http://sequel.jeremyevans.net/rdoc-plugins/files/lib/sequel/extensions/error_sql_rb.html # Shoryuken Source: https://docs.appsignal.com/ruby/integrations/shoryuken <VersionRequirements /> [Shoryuken] sho-ryu-ken is a super-efficient [AWS SQS][aws-sqs] thread-based message processor. No manual installation is required if Shoryuken is part of a Rails app. If you're using a standalone Shoryuken app, please see our [integration guide][integration-guide]. Instrumentation for Shoryuken is enabled automatically if the Shoryuken gem is detected on AppSignal start. ## Batch support If an app uses worker with the `:batch => true` option, multiple messages are processed by a worker in the same tick. An upgrade is required to Ruby gem `2.11.3` or higher, which adds support for the batch option. <CodeGroup> ```ruby Ruby theme={null} # my_worker.rb class MyWorker include Shoryuken::Worker shoryuken_options :queue => "batched", :batch => true def perform(sqs_msg, body) # Do stuff puts "Performing BatchedWorker job: #{body}" sleep 1 end end ``` </CodeGroup> ## Example application We have an example application for a standalone Shoryuken application available in our [examples repository][example-app] on GitHub. [aws-sqs]: https://aws.amazon.com/sqs/ [integration-guide]: /ruby/instrumentation/integrating-appsignal.html [shoryuken]: https://github.com/phstc/shoryuken [example-app]: https://github.com/appsignal/appsignal-examples/tree/shoryuken # Sidekiq Source: https://docs.appsignal.com/ruby/integrations/sidekiq <VersionRequirements /> [Sidekiq](http://sidekiq.org) is a simple and efficient background processor for Ruby. It's also the processor we use to process jobs in AppSignal. When AppSignal detects Sidekiq metrics, it will create an [Magic Dashboard](#magic-dashboard), allowing you to monitor core metrics visually. ## Sidekiq monitoring for Ruby on Rails apps The AppSignal Ruby gem automatically inserts a listener into the Sidekiq server middleware stack if the `Sidekiq` module is present if you use Rails. No further action is required. The Sidekiq integration is compatible with [Active Job](/ruby/integrations/active-job). ## Sidekiq monitoring for Ruby apps Adding this config should only be necessary when Sidekiq doesn't automatically load AppSignal through the app's framework, like Rails. Add this snippet to your Sidekiq config with the right environment and name: <CodeGroup> ```ruby Ruby theme={null} require 'appsignal' Sidekiq.configure_server do |config| config.on(:startup) do # Start AppSignal Appsignal.start end config.on(:shutdown) do # Stop the agent Appsignal.stop('Sidekiq shutdown') end end ``` </CodeGroup> ## Performance monitoring Once AppSignal begins reporting Sidekiq metrics, AppSignal will give you performance insights via: * [Event timeline](#event-timeline) * [Error tracking](#error-tracking) * [Incident grouping](#incident-grouping) * [Sample breakdown](#sample-breakdown) ### Event timeline `perform_job.sidekiq` events will be shown in the event timeline on the performance incident detail page: <img alt="Example event timeline" /> ### Error tracking Track exceptions that occur when running Sidekiq jobs. When Sidekiq encounters a problem before or after a job has been processed, such as parsing JSON from Redis, it will raise an error. This error is reported under the SidekiqInternal action on the background namespace, as the job context is unknown when the error occurs. <img alt="Example sidekiq error" /> #### Report errors on job discard <Compatibility /> Set the [`sidekiq_report_errors` config option](/ruby/configuration/options#option-sidekiq_report_errors) to `discard` to only report errors when a job is discarded. When a job is discarded, all job retries have been exhausted, and the job is no longer retried. Read the [Sidekiq documentation](https://github.com/sidekiq/sidekiq/wiki/Error-Handling) to learn more about Sidekiq exception handling and failed job retries. <Warning> When using Sidekiq with Active Job's retry system, configure it [to report errors only on discard](/ruby/integrations/active-job#report-errors-on-job-discard), so that it won't report errors multiple times. After the Active Job retries are exhausted, the Sidekiq retry system will take over. Disable the Sidekiq retry system if this is unwanted behavior. </Warning> ### Incident grouping Job names are automatically detected based on the Sidekiq worker class name and suffixed with the `perform` method name, resulting in something like: `MyWorker#perform`. <img alt="Example performance incident grouping" /> ### Sample performance Sample breakdowns allow you to review Sidekiq's performance quickly and spot performance problems without having to dive deep into the details. <img alt="Example Sidekiq performance sample" /> ## Magic dashboard When AppSignal receives Sidekiq metrics, it will create a Sidekiq magic dashboard, available from the dashboard section of the AppSignal app. The Sidekiq magic dashboard will have the following graphs: | Graph | Metrics | Tags | | ------------------------------------------------------ | ------------------------------------------------------------------ | ------------------------------------- | | [Connection count](#connection-count-graph) | `sidekiq_connection_count` | `hostname` | | [Duration per worker](#duration-per-worker-graph) | `transaction_duration` | <li>`action`</li><li>`namespace`</li> | | [Job status per queue](#job-status-per-queue-graph) | `sidekiq_queue_job_count` | <li>`status`</li><li>`queue`</li> | | [Overall job status](#overall-job-status-graph) | `sidekiq_job_count` | <li>`status`</li><li>`hostname`</li> | | [Queue latency](#queue-latency-graph) | `sidekiq_queue_latency` | <li>`hostname`</li><li>`queue`</li> | | [Queue length](#queue-length-graph) | `sidekiq_queue_length` | <li>`hostname`</li><li>`queue`</li> | | [Redis memory usage](#redis-memory-usage-graph) | <li>`sidekiq_memory_usage`</li><li>`sidekiq_memory_usage_rss`</li> | `hostname` | | [Throughput per worker](#throughput-per-worker-graph) | `transaction_duration` | <li>`action`</li><li>`namespace`</li> | | [Worker/processes count](#workerprocesses-count-graph) | <li>`sidekiq_worker_count`</li><li>`sidekiq_process_count`</li> | `hostname` | Tags give you a contextual breakdown of Sidekiq performance information. AppSignal reports the following tags for Sidekiq jobs: | Name | Description | | ----------- | ----------------------------------------------------------------------------------------------------------------- | | `action` | The name of the action the metric was reported from (e.g., `YourWorker#perform`). | | `hostname` | The name of the host the metric was reported from. | | `namespace` | The name of the namespace the metric was reported from. | | `queue` | Named queue in which jobs are processed, e.g. `default` or `mailer`. | | `status` | Status of each job, either `processed` or `failed`. <br />Jobs that are `failed` are also counted as `processed`. | Each tag will be represented with a colored line on the graph: <img alt="Example Sidekiq dashboard" /> ### Connection count graph The Connection count graph shows the count of Sidekiq connections per host. You can use the Connection count graph to monitor Sidekiq connections per host, spot connection trends and bottlenecks, and optimize resources. ### Duration per worker graph The Duration per worker graph shows the amount of time that it took for jobs to execute, grouped by namespace and action. You can use the Duration per worker graph to monitor the performance of workers per action and namespace, giving you a helicopter view of Sidekiq performance and allowing you to quickly identify and investigate spikes in duration time. ### Job status per queue graph The job status per queue with a priority graph shows the number of jobs that were executed, grouped by their resulting status, by the queue in which they were queued. You can use the Job status per queue graph to monitor job error counts and performance based on queue, identify bottlenecks, and optimize your background jobs for scalability. ### Overall job status graph The overall job status graph shows the number of expected Sidekiq jobs per status and namespace. You can use the Overall job status graph to monitor failed jobs and track job distribution across namespaces. ### Queue latency graph The Queue latency graph shows the latency the queue experienced at the time of measurement. [Sidekiq calculates this](https://github.com/mperham/sidekiq/wiki/API) by subtracting the time the last job was enqueued from the time of measurement. This value is reported as milliseconds. You can use the Queue latency graph to spot delays in processing jobs, detect queue congestion, and understand how quickly background jobs start. ### Queue length graph The Queue length graph shows the length of Sidekiq queues per queue and namespace. You can use the Queue length graph to monitor queue performance and spot and solve Sidekiq bottlenecks. ### Redis memory usage graph The Redis memory usage graph shows: * The Virtual Memory Size memory usage of Redis (`sidekiq_memory_usage_rss`) * The Resident Set Size memory usage of Redis (`sidekiq_memory_usage_rss`) You can use the Redis memory usage graph to monitor Sidekiq's memory usage, improve resource management, and optimize memory-intensive jobs. ### Throughput per worker graph The Throughput per worker graph shows the number of jobs that were executed, grouped by hostname. You can use this graph to monitor worker performance, grouped by the class that defines the job. ### Worker/processes count graph The Worker/processes count graph shows the number of Sidekiq workers and executed processes. You can use the Worker/processes count graph to manage workload distribution, optimize resource allocation, and identify performance problems. ## Hostname configuration AppSignal attempts to detect the hostname of the Redis instance your Sidekiq instance uses to store its queues. If the detection is not accurate, it's possible to customize the hostname configuration by overriding the default Sidekiq probe. First, you'll need to [override the default Sidekiq probe](/ruby/instrumentation/minutely-probes#overriding-default-probes) by registering a new probe with the same name (`:sidekiq`). This probe will need a configuration hash, including the `:hostname` key, with the new hostname value. By specifying the `:hostname` config option in the Sidekiq minutely probe, the metrics will be tagged with the given hostname value. The `:hostname` config option value is not used to establish a Redis or Sidekiq connection. For example: <CodeGroup> ```ruby Ruby theme={null} # config/initializers/appsignal.rb or a file that's loaded on boot # Ruby gem 2.11.0 and newer Appsignal::Minutely.probes.register( :sidekiq, # Use the same key as the default Sidekiq probe to override it Appsignal::Probes::SidekiqProbe.new(:hostname => "my_sidekiq_hostname") ) # Ruby gem 2.10.x and older Appsignal::Minutely.probes.register( :sidekiq, # Use the same key as the default Sidekiq probe to override it Appsignal::Hooks::SidekiqProbe.new(:hostname => "my_sidekiq_hostname") ) ``` </CodeGroup> In version 2.11.0 of the Ruby gem, the `SidekiqProbe` constant was moved to its own module. Upon calling the constant, a warning will be printed and logged. Update to the new constant name `Appsignal::Probes::SidekiqProbe` to remove the warning. # Sinatra Source: https://docs.appsignal.com/ruby/integrations/sinatra [Sinatra](http://www.sinatrarb.com/) applications are officially supported. Instrumenting Sinatra applications requires some manual setup. Follow the installation steps in AppSignal, starting by clicking 'Add app' on the [accounts screen](https://appsignal.com/accounts). <Note> Is your application using a combination of Rails, Grape, Hanami, Padrino or Sinatra? Follow our guide for [instrumenting multiple Rack applications](/ruby/integrations/rack-libraries). </Note> ## Installation After installing the AppSignal gem, add the AppSignal integration after requiring `sinatra` (or `sinatra/base`). <CodeGroup> ```ruby Ruby theme={null} require "appsignal" # Add this require require "sinatra" # or require "sinatra/base" # Load the Sinatra integration Appsignal.load(:sinatra) # Start AppSignal Appsignal.start # For Ruby gem 3.11 and older require "appsignal/integrations/sinatra" ``` </CodeGroup> Then, create the AppSignal configuration file. For more details on configuring AppSignal, see the [Ruby configuration](/ruby/configuration) page. After these steps, start your Sinatra app and wait for data to arrive in AppSignal. ## Ignoring errors To ignore a specific Sinatra error, set the `Sinatra.skip_appsignal_error` flag in the request environment. This flag will tell AppSignal to ignore the error that occurs during the request and not report it to AppSignal. Only ignore errors like this if you need to ignore errors from a Sinatra app using code. See the [`ignore_errors` option](/guides/filter-data/ignore-errors) to ignore it for the entire app. To avoid being notified about an error, see [our notification settings](/application/notification-settings). <CodeGroup> ```ruby Ruby theme={null} get "/" do env["sinatra.skip_appsignal_error"] = true # Add this line to an endpoint or callback raise "uh oh" # Example error, don't copy this end ``` </CodeGroup> # Solid Queue Source: https://docs.appsignal.com/ruby/integrations/solidqueue [Solid Queue](https://github.com/rails/solid_queue) is a DB-based queueing backend for Active Job. AppSignal's Solid Queue integration allows you to track enqueued job executions and any events the jobs perform. ## Active Job support The Solid Queue integration works out-of-the-box with our [Active Job integration](/ruby/integrations/active-job). ## Example apps We've added a Rails 7 + Solid Queue [example app](https://github.com/appsignal/test-setups/tree/main/ruby/rails7-solid-queue) to our [test-setups repository](https://github.com/appsignal/test-setups). Please take a look if you're having trouble getting AppSignal for Solid Queue configured. # ViewComponent gem Source: https://docs.appsignal.com/ruby/integrations/view-component <VersionRequirements /> The AppSignal gem can instrument events emitted by the [ViewComponent](https://viewcomponent.org/) Ruby gem. In order for AppSignal to be able to instrument these events, ViewComponent must be configured to emit these events. For example, in your `config/application.rb` file: <CodeGroup> ```ruby Ruby theme={null} # config/application.rb module MyRailsApp class Application < Rails::Application # add the following lines config.view_component.instrumentation_enabled = true config.view_component.use_deprecated_instrumentation_name = false end end ``` </CodeGroup> Events for ViewComponent components rendered by your application will appear in the event timeline of your application's performance actions. # Webmachine Source: https://docs.appsignal.com/ruby/integrations/webmachine <VersionRequirements /> ## Installation A [Webmachine](https://github.com/webmachine/webmachine-ruby/) application requires a few manual steps to get working. 1. Create the AppSignal configuration file or configure it with environment variables. For more details on configuring AppSignal, see the [Ruby configuration](/ruby/configuration) page. 2. Make sure AppSignal is required, `require "appsignal"`. 3. Configure AppSignal using `Appsignal.config`. 4. Start AppSignal using `Appsignal.start`. An example of a Webmachine `app.rb` file: <CodeGroup> ```ruby Ruby theme={null} # app.rb require "webmachine" require "appsignal" Appsignal.start class MyResource < Webmachine::Resource def to_html "<html><body>Hello, world!</body></html>" end end # Start a web server to serve requests via localhost MyResource.run ``` </CodeGroup> After these steps, start your Webmachine app and wait for data to arrive in AppSignal. # Services and integrations Source: https://docs.appsignal.com/services-integrations Browse all platforms, services, and integrations that work with AppSignal. Find setup guides for your hosting provider, log source, notification channel, and more. AppSignal works with the platforms, services, and tools you already use. Browse the sections below to find setup guides for your stack. ## Hosting and deploy platforms Set up deploy markers, host metrics, and log forwarding for your hosting provider. <CardGroup> <Card title="Heroku" icon="cloud" href="/heroku/setup"> Metrics, dashboards, deploy markers, and logs </Card> <Card title="Vercel" icon="triangle" href="/vercel/overview"> Logs, Speed Insights, and traces </Card> <Card title="Kubernetes" icon="dharmachakra" href="/kubernetes/metrics"> Cluster and container metrics </Card> <Card title="Render" icon="cloud" href="/render/setup"> Metrics, dashboards, deploy markers, and logs </Card> <Card title="Hatchbox" icon="rocket" href="/application/markers/deploy-markers#hatchbox-support"> Deploy markers via connected account </Card> <Card title="Kamal" icon="ship" href="/application/markers/deploy-markers#kamal-support"> Automatic deploy markers </Card> <Card title="Docker" icon="docker" href="/application/markers/deploy-markers#docker-support"> Deploy markers for containerized apps </Card> <Card title="Clever Cloud" icon="cloud" href="/logging/platforms/clevercloud"> Log forwarding </Card> <Card title="Gigalixir" icon="cloud" href="/logging/platforms/gigalixir"> Log drain </Card> <Card title="Netlify" icon="cloud" href="/logging/platforms/netlify"> Log forwarding </Card> <Card title="Scalingo" icon="cloud" href="/logging/platforms/scalingo"> Log drain </Card> </CardGroup> ## Cloud services and log sources Forward logs and metrics from cloud infrastructure to AppSignal. <CardGroup> <Card title="AWS CloudWatch logs" icon="aws" href="/logging/platforms/cloudwatch"> Forward logs via Amazon Data Firehose </Card> <Card title="AWS CloudWatch logs (CloudFormation)" icon="aws" href="/logging/platforms/cloudwatch-cloudformation"> Automate log streaming setup with a CloudFormation template </Card> <Card title="AWS CloudWatch metrics" icon="aws" href="/metrics/cloudwatch"> Stream CloudWatch metrics via Amazon Data Firehose </Card> <Card title="AWS CloudWatch metrics (CloudFormation)" icon="aws" href="/metrics/cloudwatch-cloudformation"> Automate metric streaming setup with a CloudFormation template </Card> <Card title="Vector" icon="diagram-project" href="/vector"> Forward logs from any Vector pipeline </Card> <Card title="NGINX" icon="server" href="/metrics/nginx"> Collect NGINX metrics </Card> </CardGroup> ## Notifications and incident management Send alerts and incidents from AppSignal to your team's communication and on-call tools. <CardGroup> <Card title="Slack" icon="slack" href="/application/integrations/slack"> Receive alerts in Slack channels </Card> <Card title="Microsoft Teams" icon="microsoft" href="/application/integrations/teams"> Receive alerts in Teams channels </Card> <Card title="Discord" icon="discord" href="/application/integrations/discord"> Receive alerts in Discord channels </Card> <Card title="Google Chat" icon="google" href="/application/integrations/hangouts"> Receive alerts in Google Chat spaces </Card> <Card title="PagerDuty" icon="bell" href="/application/integrations/pagerduty"> Trigger PagerDuty incidents from alerts </Card> <Card title="OpsGenie" icon="bell" href="/application/integrations/opsgenie"> Create OpsGenie alerts from incidents </Card> <Card title="Squadcast" icon="bell" href="/application/integrations/squadcast"> Route incidents to Squadcast </Card> <Card title="Webhooks" icon="webhook" href="/application/integrations/webhooks"> Send alert data to any HTTP endpoint </Card> <Card title="All Quiet" icon="bell" href="https://docs.allquiet.app/integrations/inbound/appsignal"> Route AppSignal alerts via the All Quiet webhook </Card> <Card title="ilert" icon="bell" href="https://docs.ilert.com/inbound-integrations/appsignal"> Route AppSignal alerts via the ilert webhook </Card> <Card title="Zenduty" icon="bell" href="https://www.zenduty.com/docs/appsignal-integration/"> Route AppSignal alerts via the Zenduty webhook </Card> </CardGroup> ## Issue tracking and source control Create issues and link backtraces to your codebase directly from AppSignal. <CardGroup> <Card title="GitHub" icon="github" href="/application/integrations/github"> Link repos, create issues, and link backtraces </Card> <Card title="GitLab" icon="gitlab" href="/application/integrations/gitlab"> Create GitLab issues from incidents </Card> <Card title="Jira" icon="jira" href="/application/integrations/jira"> Create Jira issues from incidents </Card> <Card title="Linear" icon="bars-progress" href="/application/integrations/linear"> Create Linear issues from incidents </Card> <Card title="Asana" icon="list-check" href="/application/integrations/asana"> Create Asana tasks from incidents </Card> <Card title="Trello" icon="trello" href="/application/integrations/trello"> Create Trello cards from incidents </Card> <Card title="Shortcut" icon="list-check" href="/application/integrations/shortcut"> Create Shortcut stories from incidents </Card> </CardGroup> ## Dashboards and reporting Push AppSignal data to external dashboards. <CardGroup> <Card title="Geckoboard" icon="chart-pie" href="/application/integrations/geckoboard"> Display AppSignal data in Geckoboard </Card> </CardGroup> ## AppSignal tools Additional tools for sending data to AppSignal or extending your setup. <CardGroup> <Card title="Collector" icon="server" href="/collector"> Receive and forward OpenTelemetry data </Card> <Card title="Standalone agent" icon="microchip" href="/standalone-agent/installation"> Monitor host metrics without an SDK </Card> <Card title="Wrap" icon="terminal" href="/wrap"> Monitor any process with a wrapper script </Card> <Card title="AppSignal API" icon="code" href="/api"> Access data and manage resources via REST API </Card> <Card title="MCP server" icon="robot" href="/mcp-server"> Query AppSignal from AI assistants </Card> </CardGroup> *** Don't see what you need? AppSignal supports any tool or service that exports [OpenTelemetry](/opentelemetry) data. You can also reach out to [support@appsignal.com](mailto:support@appsignal.com). # AppSignal Standalone agent configuration Source: https://docs.appsignal.com/standalone-agent/configuration Configuring the AppSignal standalone agent is important because, without it, the standalone agent won't know which application it is reporting data for. In this documentation we'll explain how and what can be configured in the standalone agent and how the configuration is loaded. ## Minimal configuration With a minimal configuration AppSignal will receive enough information to report the data collected by the agent from one of your apps. A minimal configuration requires the following configuration options to be set: * [App name](/standalone-agent/configuration/options#option-app_name) * [App environment](/standalone-agent/configuration/options#option-environment) * [Push API key](/standalone-agent/configuration/options#option-push_api_key) ## Configuration methods ### Configuration file The AppSignal standalone agent can be configured with a configuration file. This method is required for the [Linux package installation method][linux package]. You need to find, or create, the configuration file at `/etc/appsignal-agent.conf`. Once you've found or created a configuration file can then configure the agent with the config options listed on the [options page][options]. #### Example configuration file Below is an example of an `appsignal-agent.conf` configuration file. For the full list of options, please see the [configuration options][options] page. <CodeGroup> ```toml TOML theme={null} # /etc/appsignal-agent.conf push_api_key = "0000-0000-0000-000" app_name = "My app name" environment = "production" hostname = "hostname" ``` </CodeGroup> ### System environment variable Another way of configuring AppSignal is by using system environment variables on the host the application AppSignal is monitoring is running on. This configuration method is used by the [standalone agent Docker image][docker image]. It can also be used for the [Linux package][linux package] in combination with the [configuration file](#configuration-file). Make sure these environment variables are configured in the way that's compatible with your Operating System and that the configuration get loaded before the standalone agent is started. The [configuration options][options] page lists each config option's equivalent system environment variable. You can use these variables to configure the standalone agent, for example when configuring your app name: <CodeGroup> ```sh Shell theme={null} # Common Linux Bash example export APPSIGNAL_APP_NAME="My app" ``` </CodeGroup> [linux package]: /standalone-agent/installation/linux-package.html [docker image]: /standalone-agent/installation/docker-image.html [options]: /standalone-agent/configuration/options.html # AppSignal Standalone agent config load order Source: https://docs.appsignal.com/standalone-agent/configuration/load-order The AppSignal standalone agent can be configured using environment variables or a configuration file. The configuration is loaded in a four step process, loading the configuration from different sources. ## Load orders * 1. [Agent defaults](#1-agent-defaults) * 2. [System detected settings](#2-system-detected-settings) * 3. [Environment variables](#3-environment-variables) * 4. [Config file](#4-config-file) ## 1. Agent defaults The agent starts with loading its default configuration, setting default paths and enabling certain features. The agent defaults can be found on the [options page][options]. ## 2. System detected settings The agent detects what kind of system it's running on and configures itself accordingly. If a configuration option looks at the system to set its default, this will be listed on the [options page][options]. For example, when it's running inside a container based system (such as Docker and Heroku) it sets the configuration option `running_in_container` to `true` and enables or disables host metrics automatically. ## 3. Environment variables The agent will look for its configuration in environment variables. See the [options page][options] for available configuration options. Environment variables can be in global environment configurations that are loaded on boot for installed Linux packages and set in scripts before calling the `appsignal-agent` process. <CodeGroup> ```bash Bash theme={null} export APPSIGNAL_APP_NAME="my custom app name" # start the agent here ``` </CodeGroup> When AppSignal environment variables are found for configuration options, these will override all given configuration options from previous steps. ## 4. Config file This configuration source is used by the [Linux package installation](/standalone-agent/installation/linux-package). It is also loaded using the `--config` CLI option when calling the `appsignal-agent` process manually. The path of this configuration file is `/etc/appsignal-agent.conf` for the Linux package installation. If the standalone agent is called manually with the `--config` option, the file must be at the place specified with the `--config` option. For example, `appsignal-agent --config /path/to/config/appsignal.conf` will look for the file at `/path/to/config/appsignal.conf`. When AppSignal environment variables are found for configuration options, these will override all given configuration options from previous steps. [options]: /standalone-agent/configuration/options.html # Standalone agent configuration options Source: https://docs.appsignal.com/standalone-agent/configuration/options The following list includes all configuration options with the name of the environment variable and the name of the key in the configuration file. For more information on how to configure the Standalone AppSignal Agent with a configuration file or using environment variables, see our [configuration](/standalone-agent/configuration) section. ## Available options * Required options * [`app_name`](#option-app_name) * [`environment`](#option-environment) * [`push_api_key`](#option-push_api_key) * Options * [`bind_address`](#option-bind_address) * [`ca_file_path`](#option-ca_file_path) * [`cpu_count`](#option-cpu_count) * [`dns_servers`](#option-dns_servers) * [`enable_host_metrics`](#option-enable_host_metrics) * [`enable_http`](#option-enable_http) * [`enable_nginx_metrics`](#option-enable_nginx_metrics) * [`enable_opentelemetry_http`](#option-enable_opentelemetry_http) * [`enable_statsd`](#option-enable_statsd) * [`filter_parameters`](#option-filter_parameters) * [`filter_session_data`](#option-filter_session_data) * [`host_role`](#option-host_role) * [`hostname`](#option-hostname) * [`http_proxy`](#option-http_proxy) * [`ignore_actions`](#option-ignore_actions) * [`ignore_errors`](#option-ignore_errors) * [`ignore_namespaces`](#option-ignore_namespaces) * [`log_level`](#option-log_level) * [`nginx_port`](#option-nginx_port) * [`opentelemetry_port`](#option-opentelemetry_port) * [`push_api_endpoint`](#option-push_api_endpoint) * [`running_in_container`](#option-running_in_container) * [`send_environment_metadata`](#option-send_environment_metadata) * [`send_params`](#option-send_params) * [`send_session_data`](#option-send_session_data) * [`statsd_port`](#option-statsd_port) * [`working_dir_path`](#option-working_dir_path) ## app\_name <a /> | Field | Value | | ---------------------- | ------------------------------ | | Config file key | `app_name` | | System environment key | `APPSIGNAL_APP_NAME` | | Required | yes | | Type | `String` | | Default value | nil (This is unset by default) | ### Description Name of your application as it should be displayed on AppSignal.com. <Note> **Note**: Changing the name or [environment](#option-env) of an existing app will create a new app on AppSignal.com. </Note> ## environment <a /> | Field | Value | | ---------------------- | ------------------------------ | | Config file key | `environment` | | System environment key | `APPSIGNAL_APP_ENV` | | Required | yes | | Type | `String` | | Default value | nil (This is unset by default) | ### Description The environment of the app to be reported to AppSignal. <Note> **Note**: Changing the [name](#option-name) or environment of an existing app will create a new app on AppSignal.com. </Note> ## push\_api\_key <a /> | Field | Value | | ---------------------- | ------------------------------ | | Config file key | `push_api_key` | | System environment key | `APPSIGNAL_PUSH_API_KEY` | | Required | yes | | Type | `String` | | Default value | nil (This is unset by default) | ### Description The organization-level authentication key to authenticate with our Push API. Read more about the [AppSignal Push API key](/appsignal/terminology#push-api-key). ## bind\_address <a /> | Field | Value | | ----------------------- | ------------------------ | | Config file key | `bind_address` | | System environment key | `APPSIGNAL_BIND_ADDRESS` | | Required | no | | Type | `String` | | Default value | `127.0.0.1` | | Available since version | `0.0.24` | ### Description A valid IPv4 address the AppSignal agent uses as a binding for its TCP and UDP servers. Use a specific address if you only want the agent to listen to requests made to that address. Set this option to `0.0.0.0` to allow to receive requests from hosts using any IP address. By default it only listens to requests made on the same host. This option is applied to all the agent servers ([StatsD](#option-enable_statsd), [OpenTelemetry](#option-enable_opentelemetry_http) and [NGINX](#option-enable_nginx_metrics)). ## ca\_file\_path <a /> | Field | Value | | ---------------------- | ------------------------ | | Config file key | `ca_file_path` | | System environment key | `APPSIGNAL_CA_FILE_PATH` | | Required | no | | Type | `String` | | Default value | Defaults to system CAs. | ### Description * Configure the path of the SSL certificate file. Use this option to point to another certificate file if there's a problem connecting to our API. <Note> **Note**: The specified path cannot contain Operating Specific file system abstractions, such as the homedir symbol `~` for \*NIX systems. This will be seen as a malformed path. </Note> ## cpu\_count <a /> | Field | Value | | ----------------------- | --------------------- | | Config file key | `cpu_count` | | System environment key | `APPSIGNAL_CPU_COUNT` | | Required | no | | Type | `Float` | | Default value | `undefined` | | Available since version | `0.34.1` | ### Description The available CPU capacity of the host, in number of CPUs. This is used to calculate the CPU usage percentage in the host metrics. If not set, the agent will attempt to automatically detect this from cgroups. The number of CPUs can be a fraction, e.g. `0.5`. ## dns\_servers <a /> | Field | Value | | ---------------------- | ------------------------------ | | Config file key | `dns_servers` | | System environment key | `APPSIGNAL_DNS_SERVERS` | | Required | no | | Type | `String` | | Default value | nil (This is unset by default) | ### Description Configure DNS servers for the AppSignal agent to use. ```yaml YAML theme={null} # /etc/appsignal-agent.conf dns_servers = "8.8.8.8,8.8.4.4" ``` If you're affected by our [DNS timeouts](/support/known-issues#dns-timeouts), try setting a DNS server manually using this option that doesn't use more than **4** dots in the server name. * Acceptable values: `8.8.8.8`, `my.custom.local.server`. * Not acceptable values: `foo`, `my.awesome.custom.local.dns.server`. If the DNS server cannot be reached the agent will fall back on the host's DNS configuration and output a message in the `appsignal.log` file: `A problem occurred while setting DNS servers`. ## enable\_host\_metrics <a /> | Field | Value | | ----------------------- | ------------------------------------------------------------------------------------ | | Config file key | `enable_host_metrics` | | System environment key | `APPSIGNAL_ENABLE_HOST_METRICS` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `true` / detected by system | | Available since version | `0.0.1` | | | <ul><li>`0.0.26`: Disabled by default in the appsignal/agent Docker image.</li></ul> | ### Description Set this option to `false` to disable [host metrics](/metrics/host-metrics) collection. On Heroku and Dokku host metrics are disabled by default. This is done because these systems will report inaccurate metrics from within the containers. Host metrics collection on these systems cannot be enabled. For Heroku, use the [Heroku log drain](/heroku/host-metrics) instead. ## enable\_http <a /> | Field | Value | | ----------------------- | ------------------------------------------------------------------------------------------------------------------- | | Config file key | `enable_http` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `false` | | Available since version | `0.0.23` | | | <ul><li>`0.0.25`: Deprecated in favor of [`enable_opentelemetry_http`](#option-enable_opentelemetry_http)</li></ul> | ### Description Set this option to `true` to enable the [OpenTelemetry HTTP server](/standalone-agent/installation). When enabled, the AppSignal agent will listen to a `localhost`-bound server on port 8099. If you're running several AppSignal-instrumented applications in the same server, this configuration option can only be enabled in one of them. This is required for apps using the OpenTelemetry HTTP exporter to report data to AppSignal. ## enable\_nginx\_metrics <a /> | Field | Value | | ----------------------- | ----------------------------------------------------------------------------------- | | Config file key | `enable_nginx_metrics` | | System environment key | `APPSIGNAL_ENABLE_NGINX_METRICS` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `false` | | Available since version | `0.0.24` | | | <ul><li>`0.0.26`: Enabled by default in the appsignal/agent Docker image.</li></ul> | ### Description Set to `true` to enable the NGINX metrics server. [See the NGINX metrics documentation for details.](/metrics/nginx) When enabled, the AppSignal agent will listen to a `localhost`-bound server on port 27649. If you're running several AppSignal-instrumented applications in the same server, this configuration option can only be enabled in one of them. ## enable\_opentelemetry\_http <a /> | Field | Value | | ----------------------- | ----------------------------------------------------------------------------------- | | Config file key | `enable_opentelemetry_http` | | System environment key | `APPSIGNAL_ENABLE_OPENTELEMETRY_HTTP` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `false` / detected by system | | Available since version | `0.0.25` | | | <ul><li>`0.0.26`: Enabled by default in the appsignal/agent Docker image.</li></ul> | ### Description Set this option to `true` to enable the [OpenTelemetry HTTP server](/standalone-agent/installation). When enabled, the AppSignal agent will listen to a `localhost`-bound server on port 8099. If you're running several AppSignal-instrumented applications in the same server, this configuration option can only be enabled in one of them. This is required for apps using the OpenTelemetry HTTP exporter to report data to AppSignal. ## enable\_statsd <a /> | Field | Value | | ----------------------- | -------------------------- | | Config file key | `enable_statsd` | | System environment key | `APPSIGNAL_ENABLE_STATSD` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `true` | | Available since version | `0.0.24` | ### Description Enables the [StatsD server](/standalone-agent/statsd) in the AppSignal agent. When enabled, the AppSignal agent will listen to a `localhost`-bound server on port 8125. If you're running several AppSignal-instrumented applications in the same server, this configuration option can only be enabled in one of them. ## filter\_parameters <a /> | Field | Value | | ----------------------- | ----------------------------- | | Config file key | `filter_parameters` | | System environment key | `APPSIGNAL_FILTER_PARAMETERS` | | Required | no | | Type | `Array<String>` | | Default value | `[]` | | Available since version | `0.0.23` | ### Description List of parameter keys that should be ignored using AppSignal filtering. Their values will be replaced with `[FILTERED]` when transmitted to AppSignal. ```toml TOML theme={null} # appsignal.conf filter_parameters = ["password", "confirm_password", "secret"] ``` Read more about [parameter filtering](/application/parameter-filtering). ## filter\_session\_data <a /> | Field | Value | | ----------------------- | ------------------------------- | | Config file key | `filter_session_data` | | System environment key | `APPSIGNAL_FILTER_SESSION_DATA` | | Required | no | | Type | `Array<String>` | | Default value | `[]` | | Available since version | `0.0.23` | ### Description List of session data keys that should be ignored using AppSignal filtering. Their values will be replaced with `[FILTERED]` when transmitted to AppSignal. ```toml TOML theme={null} # appsignal.conf filter_session_data = ["secret_token_one", "secret_token_two"] ``` Read more about [session data filtering](/application/session-data-filtering). ## host\_role <a /> | Field | Value | | ----------------------- | ------------------------------ | | Config file key | `host_role` | | System environment key | `APPSIGNAL_HOST_ROLE` | | Required | no | | Type | `String` | | Default value | nil (This is unset by default) | | Available since version | `0.0.28` | ### Description Group hosts by role and generate metrics based on this role. One such metric is the `reporting_hosts` counter metric. A good role indicates what the main role of the server is, like "webserver", "processor", "api", "database", "loadbalancer", etc. ## hostname <a /> | Field | Value | | ---------------------- | -------------------- | | Config file key | `hostname` | | System environment key | `APPSIGNAL_HOSTNAME` | | Required | no | | Type | `String` | | Default value | detected from system | ### Description This overrides the server's hostname. Useful for when you're unable to set a custom hostname or when a nondescript id is generated for you on hosting services. ## http\_proxy <a /> | Field | Value | | ---------------------- | ------------------------------ | | Config file key | `http_proxy` | | System environment key | `APPSIGNAL_HTTP_PROXY` | | Required | no | | Type | `String` | | Default value | nil (This is unset by default) | ### Description If you require the agent to connect to the Internet via a proxy set the complete proxy URL in this configuration key. ## ignore\_actions <a /> | Field | Value | | ----------------------- | -------------------------- | | Config file key | `ignore_actions` | | System environment key | `APPSIGNAL_IGNORE_ACTIONS` | | Required | no | | Type | `Array<String>` | | Default value | `[]` | | Available since version | `0.0.26` | ### Description With this config option you can specify a list of actions that will be ignored by AppSignal. Everything that happens including exceptions will not be transmitted to AppSignal. This can be useful to ignore health check endpoints or other actions that you don't want to monitor. Read more about [ignoring actions](/guides/filter-data/ignore-actions). ## ignore\_errors <a /> | Field | Value | | ----------------------- | ------------------------- | | Config file key | `ignore_errors` | | System environment key | `APPSIGNAL_IGNORE_ERRORS` | | Required | no | | Type | `Array<String>` | | Default value | `[]` | | Available since version | `0.0.26` | ### Description List of error classes that will be ignored. Any exception raised with this error class will not be transmitted to AppSignal. Read more about [ignoring errors](/guides/filter-data/ignore-errors). ## ignore\_namespaces <a /> | Field | Value | | ----------------------- | ----------------------------- | | Config file key | `ignore_namespaces` | | System environment key | `APPSIGNAL_IGNORE_NAMESPACES` | | Required | no | | Type | `Array<String>` | | Default value | `[]` | | Available since version | `0.0.26` | ### Description List of namespaces that will be ignored. Any error raised or slow request that occurs in this namespace will not be send to AppSignal. Read more about [namespaces](/application/namespaces). ## log\_level <a /> | Field | Value | | ---------------------- | --------------------- | | Config file key | `log_level` | | System environment key | `APPSIGNAL_LOG_LEVEL` | | Required | no | | Type | `String` | | Default value | `info` | ### Description <Note> This option sets the severity level of AppSignal's internal logger and does not affect the [logging feature](/logging). </Note> Set the severity level of AppSignal's internal logger. If it is configured to "info" it will log all error, warning and info messages, but not log the debug messages. Setting it to the levels "debug" or "trace" is usually only needed on request from support. Setting the level to "debug"/"trace" could have a slight impact on the disk usage and IO, especially on high-traffic sites. CPU overhead is minimal with the debug option enabled. Accepted values: * error * warning * info * debug * trace ## nginx\_port <a /> | Field | Value | | ----------------------- | ---------------------- | | Config file key | `nginx_port` | | System environment key | `APPSIGNAL_NGINX_PORT` | | Required | no | | Type | `Integer` | | Default value | `27649` | | Available since version | `0.36.6` | ### Description Configure the port on which the NGINX metrics server is exposed. When AppSignal receives NGINX metrics, it listens on a `localhost`-bound server, by default on port 27649. If you're running several AppSignal-instrumented applications in the same server with NGINX metrics enabled, use this option to configure each application to listen on a different port. ## opentelemetry\_port <a /> | Field | Value | | ----------------------- | ------------------------------ | | Config file key | `opentelemetry_port` | | System environment key | `APPSIGNAL_OPENTELEMETRY_PORT` | | Required | no | | Type | `Integer` | | Default value | `8099` | | Available since version | `0.0.28` | ### Description Set this option to configure the OpenTelemetry HTTP server port of the AppSignal agent process. Configure this port if another process is already running on the machine that is also using this port to avoid conflicts. ## push\_api\_endpoint <a /> | Field | Value | | ---------------------- | ----------------------------- | | Config file key | `push_api_endpoint` | | System environment key | `APPSIGNAL_PUSH_API_ENDPOINT` | | Required | no | | Type | `String` | | Default value | `https://push.appsignal.com` | ### Description Configure the endpoint to send data to AppSignal. This setting will not have to be changed. ## running\_in\_container <a /> | Field | Value | | ----------------------- | -------------------------------- | | Config file key | `running_in_container` | | System environment key | `APPSIGNAL_RUNNING_IN_CONTAINER` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | detected by agent | | Available since version | `0.0.27` | ### Description AppSignal expects to be running on the same machine between different deploys. Set this key to `true` if the application is running in a container, such as with Docker. Newer versions of the AppSignal integration automatically detect its container environment, so no manual configuration is necessary. If you're having trouble with the automatic detection, please [contact support](mailto:support@appsignal.com). This option is set to `true` automatically on [Heroku](http://heroku.com/). ## send\_environment\_metadata <a /> | Field | Value | | ---------------------- | ------------------------------------- | | Config file key | `send_environment_metadata` | | System environment key | `APPSIGNAL_SEND_ENVIRONMENT_METADATA` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `true` | ### Description Send environment metadata about the app. For more information please read about [environment metadata](/application/environment-metadata). ## send\_params <a /> | Field | Value | | ----------------------- | -------------------------- | | Config file key | `send_params` | | System environment key | `APPSIGNAL_SEND_PARAMS` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `true` | | Available since version | `0.0.24` | ### Description Whether to skip sending request parameters to AppSignal. For more information please read about [send\_params](/application/parameter-filtering) in filtering request parameters. ## send\_session\_data <a /> | Field | Value | | ----------------------- | ----------------------------- | | Config file key | `send_session_data` | | System environment key | `APPSIGNAL_SEND_SESSION_DATA` | | Required | no | | Type | Boolean (`true` / `false`) | | Default value | `true` | | Available since version | `0.0.24` | ### Description Set this option to `false` to not send any session data with exception traces and performance issue samples. For more information please read about [request session data filtering](/application/session-data-filtering). ## statsd\_port <a /> | Field | Value | | ----------------------- | ----------------------- | | Config file key | `statsd_port` | | System environment key | `APPSIGNAL_STATSD_PORT` | | Required | no | | Type | `Integer` | | Default value | `8125` | | Available since version | `0.0.28` | ### Description Set this option to configure the StatsD HTTP server port of the AppSignal agent process. Configure this port if another process is already running on the machine that is also using this port to avoid conflicts. ## working\_dir\_path <a /> | Field | Value | | ---------------------- | ---------------------------------- | | Config file key | `working_dir_path` | | System environment key | `APPSIGNAL_WORKING_DIRECTORY_PATH` | | Required | no | | Type | `String` | | Default value | `/var/lib/appsignal-agent` | ### Description Override the location where the Standalone AppSignal Agent can store temporary files. Use this option if the default location is not suitable. See our [how AppSignal operates](/appsignal/how-appsignal-operates) page for more information about the purpose of this working directory. <Note> **Note**: The specified path cannot contain Operating Specific file system abstractions, such as the homedir symbol `~` for \*NIX systems. This will be seen as a malformed path. </Note> # Standalone AppSignal Agent installation Source: https://docs.appsignal.com/standalone-agent/installation To provide a complete picture of your application's infrastructure, you should monitor all servers your application depends on, such as database servers. You can do this by running the AppSignal Agent in Standalone Mode, which allows the agent to run without the need to start it from one of your applications processes. ## Installation methods Choose the installation method that works best for your infrastructure and what you want to monitor: * **[Linux package](/standalone-agent/installation/linux-package):** install the standalone agent directly on the host you want to monitor. This is the right choice for **host metrics monitoring** (CPU, memory, disk, network) as well as receiving StatsD, NGINX and OpenTelemetry data. The Linux package collects host metrics from the machine it runs on. * **[Docker image](/standalone-agent/installation/docker-image):** run the standalone agent as a container in Docker (Compose) or Kubernetes. This is the right choice for **receiving data from other containers** via StatsD, NGINX metrics, or OpenTelemetry. The Docker image does **not** report host metrics β€” see the [Docker image docs](/standalone-agent/installation/docker-image#host-metrics) for details on why, and what to use instead. # Standalone AppSignal Agent Docker image Source: https://docs.appsignal.com/standalone-agent/installation/docker-image The AppSignal standalone agent is available as a Docker image that can be run as a container in Docker (Compose) and Kubernetes infrastructure. This guide assumes you have Docker installed or it's used by the application's hosting platform. For information on how to install Docker locally, see [Docker's official website](https://www.docker.com/get-started). This guide shows you how to configure the AppSignal Docker image for your app, using the Docker environment variables options. ## Use cases The standalone agent Docker image is designed for **receiving data from other containers** in your infrastructure. It is a good choice for: * Receiving **StatsD metrics** from your applications (port 8125) * Receiving **OpenTelemetry data** from your applications (port 8099) * Collecting **NGINX metrics** (port 27649) All of these servers are enabled by default on the Docker image. ## Host metrics <Warning> The standalone agent **Docker image does not report host metrics**. The host metrics it would report are those of the container itself β€” in which only the agent is running β€” and are therefore not useful. </Warning> If you need host metrics monitoring (CPU, memory, disk, network), use one of these approaches instead: * **Docker host machine:** install the [Linux package](/standalone-agent/installation/linux-package) directly on the host machine that runs your Docker containers. * **Kubernetes:** use the [Kubernetes integration](/kubernetes/metrics) to monitor host metrics across your cluster. * **Individual containers:** if you're not using Kubernetes and need to monitor host metrics of specific containers, install the [Linux package](/standalone-agent/installation/linux-package) inside each container that you want to monitor. ## Docker image Add a container/service using the [appsignal/agent][image] Docker image to your application's infrastructure. If you want any apps to report data to it, like StatsD metrics, OpenTelemetry data and NGINX metrics, point them to the container's name in the application. ## Supported platforms The Docker image supports the following platforms. This list can also be viewed per Docker image tag on [Docker Hub page][image] for this image. * x86 64-bit * ARM 64-bit ## Configuration The agent can be configured with environment variables specified in the Docker run command, Docker compose options or Kubernetes configuration. In the examples below, replace `YOUR_PUSH_API_KEY` with your actual AppSignal Push API key and configure it with your application details. A full list of all configuration options can be found in the [configuration section](/standalone-agent/configuration/options). ### Docker run <CodeGroup> ```sh Shell theme={null} # Docker run example docker run \ --env APPSIGNAL_PUSH_API_KEY=YOUR_PUSH_API_KEY \ --env APPSIGNAL_APP_NAME=database-name \ --env APPSIGNAL_APP_ENV=production \ --publish "8125:8125" \ --publish "27649:27649" \ --publish "8099:8099" \ appsignal/agent ``` </CodeGroup> ### Docker compose <CodeGroup> ```yaml YAML theme={null} # docker-compose.yml example version: "3" services: appsignal: # Name of the container used as the hostname on which it can be reached image: appsignal/agent environment: - APPSIGNAL_PUSH_API_KEY=YOUR_PUSH_API_KEY - APPSIGNAL_APP_NAME=database-name - APPSIGNAL_APP_ENV=production ports: - "8125:8125" # StatsD - "27649:27649" # NGINX - "8099:8099" # OpenTelemetry ``` </CodeGroup> *** That's it! Once you've completed these steps, you should have the AppSignal standalone agent's Docker image up and running and receiving data from other apps, if configured. [image]: https://hub.docker.com/r/appsignal/agent # Standalone AppSignal Agent Linux package installation Source: https://docs.appsignal.com/standalone-agent/installation/linux-package This documentation describes how to install the AppSignal standalone agent through a Linux package on the host you want to monitor, like a database or a host without an instrumented app running on it. We are in the process of testing and packaging the standalone agent on Linux distributions that are most popular with our customers. [Let us know](mailto:support@appsignal.com) if you want to run the agent on a distribution that is not supported yet. ## Operating System ### Debian and Ubuntu The agent has been tested on Ubuntu LTS 14.04/16.04/18.04/20.04/22.04/24.04 and Debian 8/9/10/11/12. First make sure the following packages are installed. All the following commands need root permissions, you might have to use `sudo`. <CodeGroup> ```bash Bash theme={null} apt-get install curl gnupg apt-transport-https ``` </CodeGroup> Then import the GPG key from [Packagecloud](https://packagecloud.io). This is a service we use to host the repositories for us. <CodeGroup> ```bash Bash theme={null} curl -L https://packagecloud.io/appsignal/agent/gpgkey | sudo apt-key add - ``` </CodeGroup> Create a file named `/etc/apt/sources.list.d/appsignal_agent.list` that contains the repository configuration below for the OS you use. #### Ubuntu Make sure to replace `lunar` in the `appsignal_agent.list` config file below with your Ubuntu release's name. Use the following release names: * `noble` for Ubuntu 24.04 * `jammy` for Ubuntu 22.04 * `focal` for Ubuntu 20.04 * `bionic` for Ubuntu 18.04 * `xenial` for Ubuntu 16.04 * `trusty` for Ubuntu 14.04 <CodeGroup> ```conf /etc/apt/sources.list.d/appsignal_agent.list theme={null} deb https://packagecloud.io/appsignal/agent/ubuntu/ lunar main deb-src https://packagecloud.io/appsignal/agent/ubuntu/ lunar main ``` </CodeGroup> #### Debian Make sure to replace `bookworm` in the `appsignal_agent.list` config file below with your Debian release's name. Use the following release names: * `bookworm` for Debian 12 * `bullseye` for Debian 11 * `buster` for Debian 10 * `stretch` for Debian 9 * `jessie` for Debian 8 <CodeGroup> ```conf /etc/apt/sources.list.d/appsignal_agent.list theme={null} deb https://packagecloud.io/appsignal/agent/debian/ bookworm main deb-src https://packagecloud.io/appsignal/agent/debian/ bookworm main ``` </CodeGroup> #### Install the agent Then run `apt update` to get the newly added packages and install the agent. <CodeGroup> ```bash Bash theme={null} apt-get update apt-get install appsignal-agent ``` </CodeGroup> The agent has now been installed. Next up is configuring it to report to the correct app in AppSignal. ### Redhat Enterprise Linux/Centos At the moment EL version 7 and 8 are supported. First make sure the following packages are installed. All the following commands need root permissions, you might have to use `sudo`. <CodeGroup> ```bash Bash theme={null} yum install pygpgme yum-utils ``` </CodeGroup> Create a file named `/etc/yum.repos.d/appsignal_agent.repo` that contains the repository configuration below for EL7: <CodeGroup> ```conf /etc/yum.repos.d/appsignal_agent.repo theme={null} [appsignal_agent] name=appsignal_agent baseurl=https://packagecloud.io/appsignal/agent/el/7/$basearch repo_gpgcheck=1 gpgcheck=0 enabled=1 gpgkey=https://packagecloud.io/appsignal/agent/gpgkey sslverify=1 sslcacert=/etc/pki/tls/certs/ca-bundle.crt metadata_expire=300 ``` </CodeGroup> Or this config for EL8: <CodeGroup> ```conf /etc/yum.repos.d/appsignal_agent.repo theme={null} [appsignal_agent] name=appsignal_agent baseurl=https://packagecloud.io/appsignal/agent/el/8/$basearch repo_gpgcheck=1 gpgcheck=0 enabled=1 gpgkey=https://packagecloud.io/appsignal/agent/gpgkey sslverify=1 sslcacert=/etc/pki/tls/certs/ca-bundle.crt metadata_expire=300 ``` </CodeGroup> Update your local yum cache by running: <CodeGroup> ```bash Bash theme={null} yum -q makecache -y --disablerepo='*' --enablerepo='appsignal_agent' ``` </CodeGroup> And you can then install the agent: <CodeGroup> ```bash Bash theme={null} yum install appsignal-agent ``` </CodeGroup> ## Configuration The standalone agent configuration can be found at `/etc/appsignal-agent.conf`. For a list of all the available options, see the [configuration options](/standalone-agent/configuration/options) page for the standalone agent. The required Push API key can be found in the ["Push & Deploy" section](https://appsignal.com/redirect-to/app?to=info) for any app in your organization, and in the ["Add app" wizard](https://appsignal.com/redirect-to/organization?to=sites/new) for your organization. When configuring the standalone agent, pick an app name and environment that works for you. It can either be a separate app, or you can configure it for an existing app so that it reports as a new host to that app. <CodeGroup> ```conf /etc/appsignal-agent.conf theme={null} push_api_key = "<YOUR PUSH API KEY>" app_name = "<YOUR APP NAME>" environment = "<YOUR APP ENVIRONMENT>" hostname = "<YOUR HOST NAME>" ``` </CodeGroup> For example: <CodeGroup> ```conf /etc/appsignal-agent.conf theme={null} push_api_key = "0000-0000-0000-000" app_name = "My app name" environment = "production" hostname = "hostname" ``` </CodeGroup> Once you edit the configuration file you need to restart the agent. * On Ubuntu 14.04 use `service appsignal-agent restart` * On Centos/Redhat and Ubuntu 16.04 and up use `systemctl restart appsignal-agent` ## Collected metrics The agent collects [host metrics](/metrics/host-metrics) by default. You can also send [StatsD](/standalone-agent/statsd) messages to it that will be processed as custom metrics. We are eager to get feedback on this, let us know via the chat in the app or [support@appsignal.com](mailto:support@appsignal.com). # StatsD in Standalone AppSignal Agent Source: https://docs.appsignal.com/standalone-agent/statsd The standalone AppSignal Agent runs a StatsD server over UDP on `localhost` port 8125 by default. You can use this to ingest metrics from other components of your infrastructure. Any metrics added can be used as [custom metrics](/metrics/custom) within AppSignal. <Tip> If you are running several AppSignal-instrumented applications at a time in the same server, [the `enable_statsd` configuration option](/standalone-agent/configuration/options#option-enable_statsd) should be disabled for all but one of them, or [the `statsd_port` configuration option](/standalone-agent/configuration/options#option-statsd_port) should be used to expose each StatsD server on a different port. </Tip> ## Supported metrics The following StatsD metrics are currently supported: * gauge * counter * timers Other, unsupported metric types, will be ignored. ## Tagging The StatsD server supports the DogStatsD extension, which means tags for metrics are supported. ## Example The following example in Ruby demonstrates how this works using the [`statsd-instrument` gem](https://rubygems.org/gems/statsd-instrument). <CodeGroup> ```ruby Ruby theme={null} require 'statsd-instrument' StatsD.backend = StatsD::Instrument::Backends::UDPBackend.new("localhost:8125", :datadog) # Gauge StatsD.gauge 'gauge', 2.0 StatsD.gauge 'gauge_with_tags', 3.0, tags: ['hostname:frontend1'], sample_rate: 0.9 # Counter 10.times do StatsD.increment 'counter' StatsD.increment 'counter_with_key_value_tags', tags: ['hostname:frontend1'] StatsD.increment 'counter_with_only_key_tags', tags: ['important'] end # Timing 10.times do StatsD.measure 'timing', 2.55 StatsD.measure 'timing_with_tags', 3.55, tags: ['hostname:frontend1'] end ``` </CodeGroup> This is just to demonstrate, it is far more useful to use this from other languages that are not directly supported by AppSignal. You could use this to collect metrics from a PHP or .NET app for example. There are numerous tools available that can extract StatsD metrics from the JVM or various databases and web servers. We're curious to see what use cases you find, do [let us know](mailto:support@appsignal.com)! # Support Source: https://docs.appsignal.com/support * [Billing](/support/billing) * [Overview](/support/billing) * [Invoicing](/support/billing/invoicing) * [Usage](/support/billing/usage) * [Business add-ons](/support/business-add-ons) * [Contact us](mailto:support@appsignal.com) * [Debugging AppSignal](/support/debugging) * [Supported Operating Systems](/support/operating-systems) * [Maintenance policy](/support/maintenance-policy) * [Limiting requests](/support/limiting-requests) * [Known issues](/support/known-issues) * [About time](/support/about-time) * [Service status page](https://status.appsignal.com) # About time Source: https://docs.appsignal.com/support/about-time This page will explain how AppSignal handles time, why machines may report times that are not accurate, and how to synchronize app servers with NTP servers. The data that AppSignal collects from your app and app server have a timestamp attached to them. This timestamp is the time at which a HTTP request was made, background job started, metric was set, or an event started in the app. This time is then used to display graphs, sample and event data in chronological order. **⚠️ The timestamp attached to an app's data is based on the app instance server's date and time.** If an app server is not reporting approximately the current time, this may cause problems in AppSignal's processing and alerting. When an app has multiple servers, these servers need to report approximately the same time. A difference of seconds *may* not a big impact, but a factor of minutes will create undesired effects. This includes inaccurate graphs, metrics and samples, and missed notifications about Anomaly detection alerts. Read more about how data from your app and servers is sent to AppSignal's servers and how the data is then processed on our [data life cycle page](/appsignal/data-life-cycle). In particular for [Anomaly detection alerts][anomaly detection processing] ensuring the correct time is sent from an app is very important, to avoid missing alerts about metrics. ## Clock drift Computers can experience [clock drift](https://en.wikipedia.org/wiki/Clock_drift), causing it to diverge more and more from the reference clock, the current time. This means that an app server's clock can be several minutes ahead or behind of the actual time. Since the [transaction data] is using the server's timestamp, if the server is out of sync, the data that's being sent is also out of sync. Inaccurate clock times can cause problems with the reported times for samples, metrics and break reporting for [Anomaly detection triggers][anomaly detection processing]. Samples and metrics will not be shown at the actual time at which they occurred. Anomaly detection will be unable create alerts for metrics reported with inaccurate timestamps. To minimize clock drift we recommend you set up your servers to [automatically synchronize its current time][ntp sync] with an [NTP][ntp] server. ## About the future When AppSignal detects [transaction data] with timestamps based in the future (from the perspective of the AppSignal processor's current time), it will send a notification alerting the users of the app about the faulty time sent from the app. This notification is not available for (custom) metrics send from an app instance, but may be added in the future. ## Setting up NTP synchronization Synchronizing a server with NTP servers will ensure a server's time is approximately the same as a reference clock. NTP, Network Time Protocol, is the protocol used by computers to synchronize times over networks. In practice servers and personal computers poll one or more servers every so often to fetch the current time. If the returned time is different from the computer's current time, the computer updates its current time to the NTP value. Frequent polling of the NTP servers by an app server will make sure the server will never deviate too much from the reference time. AppSignal's servers are also configured to synchronize with NTP servers. The `ntp` package will synchronize a machine with NTP servers on most systems. Ubuntu offers the `timesyncd` package, as part of `systemd` since Ubuntu 16.04. The NTP setup instructions may differ for your Linux distro or Operating System, so please find a guide applicable to your setup. * [Ubuntu Time Synchronization guide](https://ubuntu.com/server/docs/network-ntp) * [Fedora NTPd guide](https://docs.fedoraproject.org/en-US/fedora/latest/system-administrators-guide/servers/Configuring_NTP_Using_ntpd/) Be sure to verify the NTP installation by checking if the server's current date and time is synced with NTP servers with the `ntpstat` or `timedatectl status` (Ubuntu/systemd) commands. [ntp sync]: #setting-up-ntp-synchronization [anomaly detection processing]: /appsignal/data-life-cycle.html#anomaly-detection [transaction data]: /appsignal/terminology.html#transactions [ntp]: https://en.wikipedia.org/wiki/Network_Time_Protocol # Billing Source: https://docs.appsignal.com/support/billing This documentation covers everything you need to know about AppSignal and billing, from trial to retention information. <CardGroup> <Card title="Invoicing" icon="receipt" href="/support/billing/invoicing"> * [Viewing your invoices](/support/billing/invoicing#viewing-your-invoices) * [Updating invoice address](/support/billing/invoicing#updating-invoice-address) * [Update billing information](/support/billing/invoicing#update-payment-method-or-billing-information) * [Change billing frequency](/support/billing/invoicing#change-billing-frequency) * [Cancelling a plan](/support/billing/invoicing#cancel-a-plan) </Card> <Card title="Usage" icon="chart-simple" href="/support/billing/usage"> * [Requests explained](/support/billing/usage#requests) * [Viewing your monthly usage](/support/billing/usage#viewing-your-monthly-usage) * [Exceeding your plan](/support/billing/usage#exceeding-your-plan) * [Reducing your usage](/support/billing/usage#reducing-your-usage) * [Throttling](/support/billing/usage#throttling-and-ignoring-actions) </Card> </CardGroup> ## Payment Currency AppSignal only supports payment in EUR (€) or USD (\$). There are no plans to offer payment in additional currencies. ## Free Tier AppSignal offers a generous [free tier](https://www.appsignal.com/plans) that includes: * 50K requests * 1GB logging * 5-day retention ## Free Trials AppSignal offers a 30-day free trial with no credit card required. You can find features and pricing on our [plans page](https://www.appsignal.com/plans). ### Can I Extend My Trial? If you would like to extend your trial, please [send us an email](mailto:support@appsignal.com), and we'll be happy to help you. ### What About Those Free Stroopwafels? [Get in touch](mailto:support@appsignal.com), and we'll see if we can get those tasty treats to you. ## Company Information AppSignal is a service run by **AppSignal B.V.** with its registered office located at Rietwaard 4 in 's-Hertogenbosch, The Netherlands. **Postage Address:** AppSignal B.V. P.O. Box 10212 1001EE Amsterdam The Netherlands **Chamber of Commerce:** 62960407 **VAT:** NL855029791B01 # Invoicing Source: https://docs.appsignal.com/support/billing/invoicing In this documentation, you can learn how to manage your invoicing settings, cancel your plan, and request the deletion of your AppSignal user account. ## Viewing Your Invoices You can review and download your invoices in your organization's billing settings, which are accessible through the Administration section of your organization's settings, or by visiting [this link](https://appsignal.com/redirect-to/organization?to=admin/invoices). ## Updating Invoice Address You can update your invoice address and invoice email via your [organization's billing settings here](https://appsignal.com/redirect-to/organization?to=admin/billing/edit), which you can also find under Administration in your organization's settings. You may need to ask your organization's administrator for access rights. They can do this via [Team management](/organization/team/members). ## Update Payment Method or Billing Information Organization owners can update the billing method or billing information for their organization by visiting the organization's billing section in the Subscription section of the Organization Settings page, or by visiting [this link](https://appsignal.com/redirect-to/organization?to=admin/billing). If you are not the owner of your organization, you may need to ask your organization's owner to give you the correct access rights. They can do this via [Team management](/organization/team/members). An organization owner can send a shareable URL to non-AppSignal users for updating credit card information, for example, to a non-technical colleague in charge of your organization's finance. To do this, navigate to the Subscription section of your Organization settings page, select "Billing", and navigate to the Change credit card section, where the shareable URL will be available for copying. ## Declined Card Payments If your card is declined, check to ensure it has sufficient funds, has not expired, and that the billing address in AppSignal matches that of the card. You can also contact your card issuer for further support. If you need help figuring out why your card is being declined, please [get in touch with us](mailto:support@appsignal.com), and we'll do our best to help you better understand why. ## Change Billing Frequency If you want to switch from a yearly plan to a monthly plan, please [contact us](mailto:support@appsignal.com) for further assistance. ## Cancel a Plan We hate to see you go, but sometimes you need to cancel your plan or [have your user account deleted](#delete-your-user-account). You can cancel an organization's plan in your organization [billing settings here](https://appsignal.com/redirect-to/organization?to=admin/invoices), which you can also find under "Billing" in the Subscription section of the Organization Settings page. Once on this page, navigate to the "Cancel plan" section and click "Go to cancelation form". You will be asked to provide a reason for your cancelation and confirm your request. If you do not wish to give a reason for canceling, you may enter "x", but we do manually review all feedback given to us! After confirming, you won't be charged any more for your plan. We may, however, still charge you for outstanding invoices we still need to collect via your credit card. You can keep using AppSignal until the end of your current billing period. After that, we may automatically remove all data we have on your applications. ## Delete Your User Account Canceling an AppSignal plan does not result in the deletion of your AppSignal user account, which may be associated with other Organization Accounts. If you'd like us to delete your user account, please [contact us](mailto:support@appsignal.com). # Usage Source: https://docs.appsignal.com/support/billing/usage In this documentation, you can learn more about AppSignal's usage policies, how your usage is calculated, and what that means for your AppSignal plan. ## Requests Explained AppSignal has request-based pricing, meaning you are charged based on the number of requests your application makes. We treat the following actions as requests: * Your app handles a request from a client. * Your app runs a background job. We measure the total monthly requests from all your applications, and we have no host limit per app. For example, 1M requests could mean ten applications generating 100K requests each on a single server or a single application generating 1M requests across 50 servers. A request always contains performance metrics and may include error metrics (in case of an error). Even though we populate different parts of AppSignal based on that data, we still consider this a single request. At this time, custom metrics, uptime monitors, and host metrics do not count against your plan's request limit. ## Logging Storage Explained Logging is a paid add-on and is charged based on storage buckets. All AppSignal plans come with 1GB of free logging storage. For logs above 1GB, you will be charged to the appropriate Logging plan, starting at 10GB. So, for example, if you need to store 8GB of logging data on average, you'd use the 10GB logging plan. We apply the same relaxed upgrade policy to our Logging plans, meaning that we'll only start an upgrade conversation if you've gone over your logging plan for 2 out of 3 months. ## Viewing Your Monthly Usage You can see a quick overview of your application's usage over the past 30 days from the [usage page](https://appsignal.com/redirect-to/organization?to=admin/billing/usage) within the AppSignal application. ## Exceeding Your Plan <Warning> If you've exceeded your plan by more than 10% for at least two out of the three most recent months, we'll give you 28 days notice to upgrade your account or reduce your usage before [automatically upgrading](#automatic-upgrades) your plan for you. </Warning> AppSignal has a [relaxed upgrade policy](https://www.appsignal.com/upgrade-policy), so there are no hard limits imposed on our customers. We will only upgrade your plan if you exceed 10% of your plan's limit for two out of the three most recent months. So you don't need to worry about your monitoring stopping during a one-off peak. You will only need to [upgrade your plan](#upgrading-your-plan) if your usage grows consistently. ### Upgrading Your plan <img alt="Screenshot of upgrade page" /> *The above screenshot is for illustration purposes only. You can find actual information on plan pricing and limits on our [pricing page](https://www.appsignal.com/plans).* You will need to [upgrade your plan](#manual-upgrades) if you've exceeded your plan for at least two out of three months by 10% or more. AppSignal will email you automatically when it's time for an upgrade. From when we first notify you, you'll have 28 days to [manually upgrade](#manual-upgrades) or [reduce your usage](#reducing-your-usage) before [automatically upgrading](#automatic-upgrades) your plan. ### Manual Upgrades To upgrade your plan manually, head to the Usage page via the app, or from a link in our email. You'll see our plan calculation based on your current usage. Once your plan has been upgraded, you'll receive a confirmation email from us. If you do not manually upgrade your plan, or [reduce your usage](#reducing-your-usage) within 28 days of us notifying you, your plan will be [automatically upgraded](#automatic-upgrades). When your plan has been upgraded, don't forget to [email us](mailto:support@appsignal.com) to redeem some free stroopwafels πŸͺ. ### Automatic Upgrades If no action is taken within 28 days of receiving your first upgrade email, and your usage fits a bigger plan, we will automatically upgrade your plan. Once your plan has been upgraded, you'll receive a confirmation email from us. ### Reduce Your Usage <Tip> If your usage has been below your current plan's usage allowance for more than 30 days, you can downgrade to a lower usage plan on the [plan page](https://appsignal.com/redirect-to/organization?to=admin/plans/new). </Tip> You have 28 days from when we first contact you to reduce your usage before your plan is automatically upgraded. #### Reducing Your Requests You can learn more about reducing your application's requests in our [Limiting Requests documentation](/support/limiting-requests). You can also click the "Inspect my usage" button on the [upgrade page](https://appsignal.com/redirect-to/organization?to=admin/upgrade) to see if your usage is still over your current plan's limits. On the 28th day, we will check your application's usage. If you are still over your plan, we will [upgrade you](#automatic-upgrades) to the one that fits your usage best. If your requests fit into your current plan, we will automatically cancel the upgrade and contact you again as per our [upgrade policy](https://www.appsignal.com/upgrade-policy). #### Reducing Your Logging If you want to reduce your logging usage, we recommend reading our ["What logs should I store?" Learning Center article](https://www.appsignal.com/learning-center/what-logs-should-i-store). ### Contact Us If you need more clarification about upgrading your application or extra support regarding reducing your usage, you can [contact us](mailto:support@appsignal.com) for assistance. We'll help you choose a plan that best suits your needs and budget. ## Throttling and Ignoring Actions Currently, we do not support throttling or allow you to limit the number of requests AppSignal collects for a single action or logs stored. Doing this would interfere with the reliability of your application's monitoring data and severely limit AppSignal's ability to give you the accurate data you need to monitor and manage your application's usage and performance properly. For example, features such as [Anomaly Detection](/anomaly-detection) would no longer be able to function correctly. # Business Add-Ons Source: https://docs.appsignal.com/support/business-add-ons Business Add-Ons are AppSignal features that are available for an additional fee. It's our alternative to an all-encompassing, pricey Enterprise Plan. AppSignal's Business Add-Ons make administration more manageable. They don't modify our core features, and the experience of using AppSignal remains the same on all plans. Our smaller customers mostly don't need these features and shouldn't have to pay for them, hence the decision to make them available as add-ons. AppSignal offers the following Business Add-Ons: * [Health Insurance Portability and Accountability Act - HIPAA - Business Associate Agreement](#hipaa-business-associate-agreement) * [Long-term Log Storage](#long-term-log-storage) * [SAML SSO](#saml-sso) ## HIPAA Business Associate Agreement You can sign a Business Associate Agreement (BAA) with AppSignal to ensure HIPAA compliance. This is required for any HIPAA-covered entity that handles PHI (Personal Health Information) and uses AppSignal. Besides putting a BAA in place, this add-on also guarantees HIPAA-compliant procedures, safeguards, and security measures. Learn more about [signing a HIPAA BBA with AppSignal](https://www.appsignal.com/add-ons/hipaa-baa). ## Long-Term Log Storage Long-Term Log Storage allows you to export and store your AppSignal logs with your S3-compatible storage. AppSignal will still store your logs for 30 days. You can read our [Long-Term Log Storage docs](/logging/long-term-log-storage) for more information. Learn more about [Long-Term Log Storage with AppSignal](https://www.appsignal.com/add-ons/long-term-log-storage). ## SAML SSO Security Assertion Markup Language (SAML) Single Sign-On (SSO) allows your team to sign into AppSignal with your existing identity provider. AppSignal's SAML SSO add-on integrates with all SAML SSO providers, such as: * Microsoft Entra ID * Google * Okta * OneLogin * WorkOS * JumpCloud Learn more about [SAML SSO with AppSignal](https://www.appsignal.com/add-ons/saml-sso). ## Managing and Purchasing Business Add-Ons Please to [contact us](mailto:support@appsignal.com) to discuss purchasing Business Add-Ons. Full pricing information is available on our [plans page](https://www.appsignal.com/plans). # Debugging AppSignal Source: https://docs.appsignal.com/support/debugging A debugging procedure used to debug problems with AppSignal or the setup in an application monitored by AppSignal. When a support request comes in at [support@appsignal.com](mailto:support@appsignal.com) we have a couple procedures to debug where a problem might come from. Since it's good to share, here are a couple of our procedures. Also see our list of [known issues](/support/known-issues) for a list of problems that might affect your application. ## Diagnose Our [Ruby gem](/ruby), [Elixir package](/elixir), [Node.js package](/nodejs/3.x) and [Python package](/python) ship with a built-in diagnose command-line tool that outputs information about the configuration of the AppSignal library and environment it's running in. All this information can help in finding a potential cause of a problem. If you open a support request, we'll usually ask you to run this first. <CodeGroup> ```bash Bash theme={null} # Ruby appsignal diagnose # Elixir mix appsignal.diagnose # With an Elixir release (`mix release`) binary: bin/your_app eval ":appsignal_tasks.diagnose()" # With a Distillery release binary: bin/your_app command appsignal_tasks diagnose # Node.js npx @appsignal/cli diagnose # Python python -m appsignal diagnose ``` </CodeGroup> The diagnose command has to be run in the directory of an application that has the AppSignal library installed. Unless the application is configured with environment variables it's necessary to provide the diagnose command with an environment. The environment will help AppSignal load the correct configuration that needs to be diagnosed. <CodeGroup> ```bash Bash theme={null} # Ruby APPSIGNAL_APP_ENV=production appsignal diagnose # --environment option support since Ruby gem version 2.0.4 appsignal diagnose --environment=production # Elixir MIX_ENV=production mix appsignal.diagnose # Or with the release binary bin/your_app command appsignal_tasks diagnose # Node.js NODE_ENV=production npx @appsignal/cli diagnose # Python APPSIGNAL_APP_ENV=production python -m appsignal diagnose ``` </CodeGroup> ### Diagnose information The diagnose command will output the following data. * Agent information * Ruby gem / Elixir package / Node.js / Python package version * Agent version * Ruby gem installation path * C-extension / Nif loaded: `yes`/`no` * Host information * Hardware architecture * Operating system * Ruby / Elixir & OTP / Node.js / Python version * Heroku detection - only visible on Heroku * Container detection * Current user is `root` user: `yes`/`no` * [Agent](/appsignal/terminology#agent) diagnostics * Starts the agent in diagnose mode * Agent configuration validation * Agent logger initialization * Agent lock file path writable check * Configuration * Environment * The Ruby gem outputs a warning if none is found. * List of configuration options * See all available configuration options: * [Ruby gem options](/ruby/configuration/options) * [Elixir package options](/elixir/configuration/options) * [Node.js package options](/nodejs/3.x/configuration/options) * [Python package options](/python/configuration/options) * Push API key validation * Tests if the Push API key that's being used is a valid key at AppSignal.com. * Path information * Tests all required paths if they are writable. Also outputs ownership of the current user. * `current_path` - path the diagnose command is run in. Should be a path for the application you're trying to debug. Usually the same as `root_path`. (Ruby only) * `root_path` - application path. AppSignal will try to find a `config/appsignal.rb`/`config/appsignal.yml` file here. (Ruby only) * `log_dir_path` - path the log file is created in. * `log_file_path` - path the log file is created. Is empty if no viable path could be found. * Installation information (Ruby only) * Something could have gone wrong during the installation of the AppSignal agent. This section outputs the `install.log` and `mkmf.log` (Makefile log) files. The following options need to be correctly configured for AppSignal to start. It's the absolute minimum, other configuration can also affect the instrumentation. * Configuration `Environment` / `env` is set. * Configuration `name` is set. * Configuration `push_api_key` is set. * Configuration `active` is set to `true`. * The Push API key validates. An internet connection is required for this. ## Configuration The configuration is key. It's important, because without it the AppSignal agent won't know which application it's instrumenting and in which environment. Using the [diagnose](#diagnose) information we see if we can find a problem with the configuration of the agent. The AppSignal agents have multiple methods of configuration. We recommend you read the configuration topic to get started, specifically the minimal required configuration, configuration load order and the configuration options pages if you're experiencing problems. * Configuration overview: [Ruby](/ruby/configuration) / [Elixir](/elixir/configuration) / [Node.js](/nodejs/3.x/configuration) / [Python](/python/configuration) * Minimal required configuration: [Ruby](/ruby/configuration/#minimal-required-configuration) / [Elixir](/elixir/configuration/#minimal-required-configuration) / [Node.js](/nodejs/3.x/configuration/#minimal-required-configuration) / [Python](/python/configuration/#minimal-required-configuration) * Configuration load order: [Ruby](/ruby/configuration/load-order) / [Elixir](/elixir/configuration/load-order) / [Node.js](/nodejs/3.x/configuration/load-order) / [Python](/python/configuration/load-order) * Configuration options: [Ruby](/ruby/configuration/options) / [Elixir](/elixir/configuration/options) / [Node.js](/nodejs/3.x/configuration/options) / [Python](/python/configuration/options) ## No data appearing There can be many reasons why an application is not being detected by AppSignal. Only when the AppSignal servers start receiving data from an application it is created in the UI on AppSignal.com; if no data is received, no application is created. When an integration is broken or not setup correctly it can take a long time to track the problem down. To rule out the AppSignal agent and its processing we can send "demo samples". <CodeGroup> ```bash Bash theme={null} # Ruby appsignal demo --environment=development # Elixir MIX_ENV=prod mix appsignal.demo # Or with the release binary bin/your_app command appsignal_tasks demo # Node.js npx @appsignal/cli demo # Python python -m appsignal demo --environment=production ``` </CodeGroup> This command sends a fake web request and error sample to the AppSignal servers for the application. Once data has been received the AppSignal servers start processing the data and create an application on AppSignal.com. In each integration this process is also used in the install command-line tool to help with the installation process. Note that the "demo" command has to be run in the directory of an application that has the AppSignal agent installed. ## Logs When there's no problem found in the diagnose information, the agent's logs are the next thing you can look into. The AppSignal agents create log files to output useful information and problems that were encountered in the agent itself. By default the agents log "info"-level logs and higher (warning & error). To log more data relevant for debugging, set the `log_level` ([Ruby](/ruby/configuration/options#option-log_level) / [Elixir](/elixir/configuration/options#option-log_level) / [Python](/python/configuration/options#option-log_level)) / `logLevel` ([Node.js](/nodejs/3.x/configuration/options#option-logLevel)) option to `debug`. ### Logs contents The AppSignal log file contains information from three different AppSignal components. It will prefix every log entry with a time stamp, component name, process PID, log level indicator and the log message itself. The available agent components are: * `process` Language specific implementation (Ruby / Elixir). * `extension` C-lang extension to the language implementation. Runs in the same process as `process`. * `agent` AppSignal Rust system agent. A separate process. ### Log message breakdown #### File logger log message breakdown ```text Text theme={null} [2016-10-19T11:06:18 (process) #11329][DEBUG] Starting appsignal ^ ^ ^ ^ ^ | | | | Message | | | Log level | | Process PID | Agent component Timestamp in host time zone ``` #### STDOUT log message breakdown For STDOUT loggers the AppSignal Ruby gem prefixes a recognizable "appsignal" prefix to the message so that specific AppSignal messages can be grepped in the parent process' log output. ```text Text theme={null} [2016-10-19T11:06:18 (process) #11329][DEBUG] appsignal: Starting appsignal ^ ^ ^ ^ ^ ^ | | | | | Message | | | | AppSignal prefix | | | Log level | | Process PID | Agent component Timestamp in host time zone ``` ### Log location There are two methods of saving logs from the AppSignal library. By writing the logs to a log-file and by printing the logs in the process' STDOUT. See the [`log` configuration](/ruby/configuration/options#option-log) for more information. Logs written to a log file are not written to your application's log files, but have their own `appsignal.log` file. Depending on the permissions of a host the agent will write the logs to a different location. The Ruby gem will first try to create a log file in an application's directory. For Ruby on Rails applications it will create a log file in the `log/` directory instead. If it has no luck creating a log file it will fall back on the system's `/tmp` directory. This is also where other AppSignal agent files are saved. The Elixir package will write the log files to the `/tmp/appsignal.log` log-file. If it completely fails to find a writable location to save its logs to, it will output them in the STDOUT of the parent application's process. This can also be configured with the `:log` option. The system agent is currently unable to log to STDOUT, so it will always log to the `appsignal.log` file even when the log is configured to STDOUT. To let AppSignal tell you where it will write its logs to, see the output of the [diagnose](#diagnose) command. ### Log rotation AppSignal does not perform log rotation for its log files. We recommend configuring a system tool such as `logrotate` to manage file size and retention. ### Standalone agent logs If you are using the AppSignal standalone agent, you can access the logs with the following command: ```bash Bash theme={null} sudo journalctl -u appsignal-agent ``` (The `sudo` command may be optional in certain environments such as containers.) ### Log files on Heroku On the [Heroku](http://heroku.com/) hosting platform the integration library will log to STDOUT automatically. Since the agent can't log to STDOUT it will continue to write to the `appsignal.log` file. On Heroku it's not possible to see the log file contents with `heroku run bash` and then read the log file, because of the way Heroku Dynos are containerized. Heroku provides an add-on called "[Heroku Exec](https://devcenter.heroku.com/articles/heroku-exec)" to allow executing commands in the same dyno container as your application. Using this add-on we can read the log file on your application's dynos. <CodeGroup> ```bash Bash theme={null} # Install the Exec add-on as described on the Heroku website: # https://devcenter.heroku.com/articles/heroku-exec $ heroku ps:exec $ cat /path/to/appsignal.log ``` </CodeGroup> ## Is the agent running? When an application with AppSignal integration starts it boots the AppSignal system agent. This agent runs as a separate process and communicates with the application. After processing instrumentation data, it is this agent that sends the data to the AppSignal servers, not the language specific agent. When the system agent is not running, no data can be processed or sent to AppSignal. It's important to know if the system agent is running. You can find it in the process list under the name `appsignal-agent`. <CodeGroup> ```bash Bash theme={null} ps aux | grep appsignal ``` </CodeGroup> Run the `ps`-command on the command-line on your host to see if the agent is running while your application is running AppSignal. ## Other questions There can be many factors at play when a problem occurs. Things to check when AppSignal doesn't seem to be working or there are no logs available. * Since when does the problem occur? * Was the agent updated? * Were other libraries updated? * What does the AppSignal agent logs say with the `log_level` option set to `debug`? * Is the [Operating System](/support/operating-systems) supported? * Did the "extension" install and load correctly? Answers should be in the ["diagnose" output](#diagnose). * Is the application running inside a containerized system? * Are the application servers's synced using [NTP](/support/about-time) to prevent clock drift? * Is your problem mentioned in our list of [known issues](/support/known-issues)? ## Creating a reproducible state If the steps described above haven't shown a cause for the problem, a good next step is to try to replicate the situation in the most minimal setup possible. Create a test application with as little configuration as possible, loading only the minimum required libraries and dependencies. With this reproducible example application we can start tracking down the cause of the problem. ## Contact us Don't hesitate to [contact us](mailto:support@appsignal.com) if you run into any issues while debugging the AppSignal agents. We're here to help. # Known issues Source: https://docs.appsignal.com/support/known-issues This page contains a list of publicly documented known and ongoing issues for AppSignal integrations. If you're experiencing any of the listed issues, please follow the described fixes or workarounds. If none are documented, please contact us at [support@appsignal.com](mailto:support@appsignal.com). Not all known issues are documented here. Only those that are taking some time to get fixed, remain an issue in some way after they have been fixed or benefit from a separate support page. See also the GitHub issue tracker for our integrations for other known issues: * [Ruby gem issue tracker](https://github.com/appsignal/appsignal-ruby/issues) * [Elixir package issue tracker](https://github.com/appsignal/appsignal-elixir/issues) * [Node.js package issue tracker](https://github.com/appsignal/appsignal-nodejs/issues) * [Python package issue tracker](https://github.com/appsignal/appsignal-python/issues) * [JavaScript for Front-end issue tracker](https://github.com/appsignal/appsignal-javascript/issues) ## List of known issues * [DNS timeouts](/support/known-issues/dns-timeouts) * Symptom: no data is being received by AppSignal. * Affected components: * AppSignal Ruby gem versions: `v2.1.x` - `v2.3.x` * AppSignal Elixir package versions: `v0.10.x` - `v1.3.x` * Systems: Linux distributions only - except Alpine Linux. # Limiting requests Source: https://docs.appsignal.com/support/limiting-requests [Our pricing](https://appsignal.com/plans) is based on the request count your application processes. This includes web requests and background jobs. We feel it's the most fair way of determining how much value your application generates. However, not all requests are equal. For example load balancer health checks that occur every 10 seconds provide no value, but are needed to keep your app up-and-running. We have created a number of (config) options to reduce (ignore) the request count for these kinds of requests. <Warning> **Warning**: Exceptions that occur in ignored actions/namespaces **will not** be sent to AppSignal. </Warning> [Custom metrics](/metrics/custom) **will** be sent if they were emitted in an ignored action/namespace. Be careful when deciding on what to ignore. Ignoring the `admin` namespace might sound like a good idea, but could backfire when your team's work isn't saved because of an error you didn't know is happening. ## Ignore actions The most specific option is to ignore a certain action (e.g. `HealthCheckController#show`), we recommend to only ignore actions that provide little value or are mostly static, such as: * Health checks * Product tour pages or other static pages More documentation about ignoring actions: * [Ignore actions for Ruby](/guides/filter-data/ignore-actions#ruby) * [Ignore actions for Elixir](/guides/filter-data/ignore-actions#elixir) * [Ignore actions for Node.js](/guides/filter-data/ignore-actions#node-js) * [Ignore actions for Python](/guides/filter-data/ignore-actions#python) **Please note:** Ignoring actions does not stop the storage of logs for those actions. ## Ignore namespaces When you have a large amount of actions you'd like to ignore, we recommend setting a custom namespace for these actions and ignore the namespace instead. This keeps the config clean. * [Documentation on setting namespaces](/application/namespaces) * [Configuring namespaces for Ruby](/guides/filter-data/ignore-namespaces#ruby) * [Configuring namespaces for Elixir](/guides/filter-data/ignore-namespaces#elixir) * [Configuring namespaces for Node.js](/guides/filter-data/ignore-namespaces#node-js) * [Configuring namespaces for Python](/guides/filter-data/ignore-namespaces#python) # Maintenance policy Source: https://docs.appsignal.com/support/maintenance-policy ## Version support for languages and packages At AppSignal we have a support policy for all our integration packages. This defines what compatibility we maintain with programming languages and packages we integrate with. We may drop support for some versions of programming languages and packages over time. Consult this page for our policy. This policy may be subject to change in the future. ## Rationale There are a lot of versions of programming languages and packages out there. We can't realistically support them all. It would take too much time to maintain and would limit our work to specific syntax and features of the languages/packages. ## Programming languages We support the maintained versions of a programming language we integrate with. Once a release becomes End of Life (EOL), we will drop support in the next major or minor release of an integration. If possible, we do this by updating the language version requirement in our package definitions so that it will fail to install on older versions. Consult the maintenance policy per language we integrate with below. If a language we support does not have a maintenance policy, we will default to supporting the latest three major releases if possible. * [Ruby maintenance policy](https://www.ruby-lang.org/en/downloads/branches/) * [Elixir maintenance policy](https://hexdocs.pm/elixir/compatibility-and-deprecations.html) * [Erlang OTP support](https://hexdocs.pm/elixir/compatibility-and-deprecations.html#compatibility-between-elixir-and-erlang-otp) is based on which version of Elixir supports which OTP version. * [Node.js maintenance policy](https://nodejs.org/en/about/releases/) * We only support the releases under "Maintenance LTS", "Active LTS" and "Current". * [Python maintenance policy](https://devguide.python.org/versions/) * We only support the releases that are in the "feature", "bugfix" and "security" states. * Front-end JavaScript support policy. * We aim for compatibility for most major browsers, down to Internet Explorer 9. All browsers older than this can only supported on a "best effort" basis, and full functionality cannot be guaranteed. * It also supports different targets: * Electron apps * Short-lived processes * Serverless functions * Statically generated apps * React Native/Expo apps ## Packages We support the maintained versions of a package we integrate with. Once a package version becomes End of Life (EOL), we will drop support in the next major or minor release of an integration. If possible, we do this by updating the package version requirement in our package definitions or in some other way. Not all packages have a maintenance policy, only supporting the latest release of their package. In this case we only support the three latest major versions, or minor versions if a package hardly ever releases a major version. This support is within reason, as long as we can continue supporting it without spending exuberant amounts of time on maintaining compatibility. ## Newer integrations For new integrations (programming languages and packages) this support policy does not apply. AppSignal will first only target the maintained, or latest, version of a language/package. We will not support older versions immediately unless relevant. ## Git branches During the support process an app may have tested a fix or new feature upon request, by including any of the AppSignal integrations via Git through a specific Git branch. These branches belong to Pull Requests which are eventually either merged or closed. Afterward the branch that belongs to the Pull Request is **removed after six months**. This may take longer at times, but no guarantees are made about the lifetime of branches beyond this point. Please update your integration to the latest released version of the packages as soon as possible. We strongly advise to *never* deploy an app to its production environment when it's installing an AppSignal integration through Git. # Supported operating systems Source: https://docs.appsignal.com/support/operating-systems The AppSignal integrations for Ruby, Elixir & Node.js contain native extensions and a separate lightweight agent process. These native extensions are supported on most Linux distributions, FreeBSD and macOS/OSX. Our Go and Python integrations only use our agent process and don't require additional packages to be installed. Like the other integrations, they only work on the supported Operating Systems listed in the [support table](#support-table). If an Operating System you use is not supported, please [get in touch][support]. ## Support table Table of different Operating Systems and architecture combinations we support. Check the notes below the table for any exceptions and version requirements. ### Integrations Our integrations include the: [Ruby gem](/ruby), [Elixir package](/elixir), [Node.js package](/nodejs) and [Python package](/python). | Β  | x86 32-bit | x86 64-bit | ARM 64-bit | | ------------------------------------------------------------------ | -------------------------------------- | -------------------------------------- | ----------------------------------------------------- | | [macOS/OSX](#macos) <sup>1</sup> | | <center><Icon icon="check" /></center> | <center><Icon icon="check" /></center> | | [Linux](#linux) | | | | | Β Β  - [Alpine Linux](#alpine-linux) | | <center><Icon icon="check" /></center> | <center>Β Β <Icon icon="check" /> <sup>2</sup></center> | | Β Β  - [CentOS](#centos) | <center><Icon icon="check" /></center> | <center><Icon icon="check" /></center> | <center><Icon icon="check" /></center> | | Β Β  - [Debian / Ubuntu](#debian-ubuntu) | <center><Icon icon="check" /></center> | <center><Icon icon="check" /></center> | <center><Icon icon="check" /></center> | | Β Β  - [Fedora](#fedora) | <center><Icon icon="check" /></center> | <center><Icon icon="check" /></center> | <center><Icon icon="check" /></center> | | [FreeBSD](#freebsd) <sup>1 3</sup> | | <center>?</center> | | | [Microsoft Windows](#microsoft-windows)<sup>4</sup> | | | | | Β Β  - [Subsystem for Linux](#microsoft-windows-subsystem-for-linux) | | <center>? <sup>4</sup></center> | | * `1`: Does not support [host metrics][host-metrics]. * `2`: Not supported for our Node.js integration. * `3`: Support level unclear, see [FreeBSD](#freeBSD). * `4`: Does not work natively on [Windows](#microsoft-windows). AppSignal does not provide official support for the [Windows Subsystem for Linux](#microsoft-windows-subsystem-for-linux). ### Components Additional components include: [Collector](/collector), [Standalone agent](/standalone-agent/installation/docker-image), [Wrap](/wrap). | Β  | x86 64-bit | ARM 64-bit | | ----------------------------- | --------------------------------------------------- | --------------------------------------------------- | | macOS/OSX | <center><Icon icon="check" /></center> | <center><Icon icon="check" /></center> | | Linux | | | | Β Β  - Alpine Linux | <center><Icon icon="check" /> <sup>1</sup></center> | <center><Icon icon="check" /> <sup>1</sup></center> | | Β Β  - CentOS | <center><Icon icon="check" /></center> | <center><Icon icon="check" /></center> | | Β Β  - Debian / Ubuntu | <center><Icon icon="check" /></center> | <center><Icon icon="check" /></center> | | Microsoft Windows<sup>2</sup> | | | | Β Β  - Subsystem for Linux | <center>? <sup>2</sup></center> | <center>? <sup>2</sup></center> | | Docker image | <center><Icon icon="check" /> <sup>3</sup></center> | <center><Icon icon="check" /> <sup>3</sup></center> | No additional dependencies have to be installed for these components unless listed in their installation guides. * `1`: Alpine Linux is only supported by [Wrap](/wrap). * `2`: Does not work natively on [Windows](#microsoft-windows). AppSignal does not provide official support for the [Windows Subsystem for Linux](#microsoft-windows-subsystem-for-linux). * `3`: [Wrap](/wrap) is not available as a Docker image. ## Linux AppSignal tries to support Linux as best as possible, but some changes in our build process have caused some problems with supporting certain Linux distributions and versions. Our agent and extension are compiled against libc, and based on which version of libc we compile against we support certain older versions of Linux distributions and some not. ### Supported versions AppSignal support for versions of libc has changed over the past few versions of the Ruby gem and Elixir package. This is the list of version of libc/musl AppSignal was compiled against over the last version of our integrations: * AppSignal for Ruby `v1.0.0` - `v2.0.x`<br /> AppSignal for Elixir `v0.0.x` - `v0.10.x` * libc `v2.5` * musl `N/A` * AppSignal for Ruby `v2.1.x` - `v2.3.x`<br /> AppSignal for Elixir `v0.11.x` - `v1.3.x` * libc `N/A` - see [DNS timeouts known issue](/support/known-issues/dns-timeouts). * musl `v1.1.16` * AppSignal for Ruby `v2.4.x` and higher<br /> AppSignal for Elixir `v1.4.x` and higher<br /> AppSignal for Node.js `v1.0.0` and higher<br /> AppSignal for Python `v0.1.0` and higher * libc `v2.15` * musl `v1.1.16` If your system uses an older libc version than AppSignal extension is compiled against, you will experience problems installing or running the AppSignal agent. If this is the case you can instead [opt-in to the musl build](#musl-build-override), which doesn't have this issue. This should no longer be a problem for AppSignal Ruby gem `v2.4.1` & Elixir package `v1.4.3` and higher, in these packages automatic detection for older libc versions was added and they will automatically switch to the musl build. **Warning for JRuby**: JRuby support on Alpine Linux (musl build) is supported since Ruby gem `2.8.0`. This scenario requires a dynamic build of the AppSignal extension, which is not supported for the musl build for older versions of the gem. You can see which version of libc your system uses by running the following command: `ldd --version 2>&1` Example of output on Ubuntu 12.04: <CodeGroup> ```bash Bash theme={null} $ ldd --version 2>&1 ldd (Ubuntu EGLIBC 2.15-0ubuntu10.18) 2.15 Copyright (C) 2012 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Written by Roland McGrath and Ulrich Drepper. ``` </CodeGroup> ### Musl build override To opt-in to the musl build manually, add the `APPSIGNAL_BUILD_FOR_MUSL` environment variable to your system environment before installing AppSignal and compiling your application. This environment variable is only needed if our auto detection does not detect the correct architecture. <CodeGroup> ```sh Shell theme={null} # For Ruby export APPSIGNAL_BUILD_FOR_MUSL=1 gem install appsignal # or with Bundler bundle install # For Elixir export APPSIGNAL_BUILD_FOR_MUSL=1 mix deps.get mix compile # For Node.js export APPSIGNAL_BUILD_FOR_MUSL=1 npm install # For Python # Not supported ``` </CodeGroup> ### Linux ARM build override The AppSignal packages will automatically detect ARM based hosts and select the agent and extension to install for ARM systems. When this detection doesn't work, opt-in to the Linux ARM build manually with the `APPSIGNAL_BUILD_FOR_LINUX_ARM` environment variable. Add it to your system environment before installing AppSignal and compiling your application. This environment variable is only needed if our auto detection does not detect the correct architecture. <Tip> Available in these packages: * Ruby gem 3.0.8 or newer. * Elixir package 2.1.8 or newer. * Node.js package 1.2.6 or newer. Not supported in our Python package. </Tip> <CodeGroup> ```sh Shell theme={null} # Set this environment variable # Note: How environment variables are set may be different for your Operating # System. export APPSIGNAL_BUILD_FOR_LINUX_ARM=1 # Run the install command, such as: bundle install, npm install, mix compile ``` </CodeGroup> ### Alpine Linux * Ruby: supports [Alpine Linux] since Ruby gem version `2.1.0`. (JRuby is not supported on Alpine Linux.) * Elixir: supports [Alpine Linux] since Elixir package version `0.11.0`. * Node.js: supports [Alpine Linux] since Node.js package version `3.0.2`. Not supported for Node.js version `14`. In AppSignal for Ruby version `2.4.0` and AppSignal for Elixir `1.4.0` we started shipping a separate build for Alpine Linux. If you upgraded from an earlier version and are have problems compiling your app, our detection isn't working properly. The following system dependencies are required for Alpine Linux: <CodeGroup> ```sh Shell theme={null} # Dependencies for the AppSignal Ruby gem apk add make gcc musl-dev musl-utils # Dependencies for the AppSignal Node.js package apk add python3 make g++ # Dependencies for the AppSignal for Elixir package version 1.7.0 and newer apk add make gcc musl-dev musl-utils # Dependencies for the AppSignal for Elixir package version 1.6.3 and older apk add make gcc musl-dev musl-utils curl ``` </CodeGroup> For all integrations, detection is based on the output from `ldd --version`. If your app is unable to call the `ldd` program or the detection is off for some reason, you can force the Alpine Linux compatible build by providing a special environment variable on install. <CodeGroup> ```sh Shell theme={null} # For Ruby export APPSIGNAL_BUILD_FOR_MUSL=1 gem install appsignal # or with Bundler bundle install # For Elixir export APPSIGNAL_BUILD_FOR_MUSL=1 mix deps.get mix compile # For Node.js export APPSIGNAL_BUILD_FOR_MUSL=1 npm install ``` </CodeGroup> #### Ruby For the Ruby gem add this to your `Gemfile`: <CodeGroup> ```ruby Ruby theme={null} gem "appsignal", ">= 2.1.0" # or a newer version ``` </CodeGroup> For the latest available version see the full list on [RubyGems.org](https://rubygems.org/gems/appsignal/versions) and if you run into any problems please [let us know][support]. #### Elixir If you're using the Elixir package, add this to the `deps` section your `mix.exs` file: <CodeGroup> ```elixir Elixir theme={null} {:appsignal, ">= 1.0.0"} # or a newer version ``` </CodeGroup> For the latest available version see the full list on [Hex.pm](https://hex.pm/packages/appsignal) and if you run into any problems please [let us know][support]. #### Node.js If you're using the Node.js package, add this to the `dependencies` section of your `package.json` file: ```text Text theme={null} "@appsignal/nodejs": "^3.0.2" ``` For the latest available version see the full list on [NPM](https://www.npmjs.com/package/@appsignal/nodejs) and if you run into any problems please [let us know][support]. ### CentOS CentOS is fully supported by the AppSignal extension. Depending on your CentOS version you may need to select another build type for AppSignal Ruby gem `v2.4.0` and AppSignal for Elixir `v1.4.0` and higher. The following system dependencies are required for CentOS: <CodeGroup> ```sh Shell theme={null} # Dependencies for the AppSignal Ruby gem and Node.js package yum install gcc gcc-c++ make openssl-devel # Dependencies for the AppSignal for Elixir package version 1.7.0 and newer yum install gcc gcc-c++ make openssl-devel # Dependencies for the AppSignal for Elixir package version 1.6.3 and older yum install gcc gcc-c++ make openssl-devel curl # Dependencies for the AppSignal for Node.js package version 2.3.4 or newer, the supported Python versions are those between Python 3.7 and Python 3.10. # Dependencies for the AppSignal for Node.js package version 2.3.3 or below, the supported Python versions are those between Python 3.5 and Python 3.8. yum install python3 ``` </CodeGroup> For CentOS 7 and higher there is no problem upgrading to AppSignal for Ruby `v2.4.0` and AppSignal for Elixir `1.4.0` and higher. For CentOS 6 and older versions you will need to opt-in to the musl build for AppSignal instead. For more information, see the [Linux section](#linux). ### Debian / Ubuntu The following system dependencies are required for Debian Linux distributions: <CodeGroup> ```sh Shell theme={null} # Dependencies for the AppSignal Ruby gem and Node.js package apt-get update apt-get install build-essential ca-certificates # Dependencies for the AppSignal for Elixir package version 1.7.0 and newer apt-get update apt-get install build-essential ca-certificates # Dependencies for the AppSignal for Elixir package version 1.6.3 and older apt-get update apt-get install build-essential ca-certificates curl # Dependencies for the AppSignal for Node.js package version 2.3.4 or newer, the supported Python versions are those between Python 3.7 and Python 3.10. # Dependencies for the AppSignal for Node.js package version 2.3.3 or below, the supported Python versions are those between Python 3.5 and Python 3.8. apt-get install python3 ``` </CodeGroup> ### Fedora The following system dependencies are required for Fedora Linux distributions: <CodeGroup> ```sh Shell theme={null} # Dependencies for the AppSignal Ruby gem dnf install gcc gcc-c++ make openssl-devel # Dependencies for the AppSignal for Elixir package version 1.7.0 and newer dnf install gcc gcc-c++ make openssl-devel # Dependencies for the AppSignal for Elixir package version 1.6.3 and older dnf install gcc gcc-c++ make openssl-devel curl # Dependencies for the AppSignal for Node.js package version 2.3.4 or newer, the supported Python versions are those between Python 3.7 and Python 3.10. # Dependencies for the AppSignal for Node.js package version 2.3.3 or below, the supported Python versions are those between Python 3.5 and Python 3.8. dnf install python3 ``` </CodeGroup> ## FreeBSD <Warning> Our level of FreeBSD support is currently unclear. Our tests show it works on FreeBSD 11, but we have not been able to see it report data on FreeBSD 12 and newer. Assume it will not report data on FreeBSD 12 and newer. </Warning> Support for FreeBSD systems was added in AppSignal for Ruby gem `2.4.0` and AppSignal for Elixir package `1.4.0`. It currently does not support the [host metrics][host-metrics] feature. The following system dependencies are required for FreeBSD Linux distributions: <CodeGroup> ```sh Shell theme={null} pkg install gcc gmake openssl-devel # Dependencies for the AppSignal for Node.js package version 2.3.4 or newer, the supported Python versions are those between Python 3.7 and Python 3.10. # Dependencies for the AppSignal for Node.js package version 2.3.3 or below, the supported Python versions are those between Python 3.5 and Python 3.8. pkg install python3 ``` </CodeGroup> ## macOS macOS (OS X) `10.14.x` and up is supported by AppSignal for Ruby, Elixir & Node.js. It currently does not support the [host metrics][host-metrics] feature. Please make sure Xcode is installed with the command line build tools. <CodeGroup> ```sh Shell theme={null} xcode-select --install # Dependencies for the AppSignal for Node.js package version 2.3.4 or newer, the supported Python versions are those between Python 3.7 and Python 3.10. # Dependencies for the AppSignal for Node.js package version 2.3.3 or below, the supported Python versions are those between Python 3.5 and Python 3.8. brew install python@3 ``` </CodeGroup> ## Microsoft Windows We currently have no plans to support the [Microsoft Windows](https://www.microsoft.com/en-us/windows/) Operating System. We do try to make the AppSignal libraries installable on Microsoft Windows without any errors or build issues so that the app it's installed in continues to operate. If you use Microsoft Windows and would like us to support it, [send us an e-mail][support]. ### Ruby To install the AppSignal Ruby gem on Microsoft Windows, make sure you have the [RubyInstaller](https://rubyinstaller.org/) DevKit installed before installing AppSignal. Otherwise there will be the following error during installation of our C-extension. We will not install the C-extension on Microsoft Windows, but the Ruby installation detects it's part of the gem and will not continue without the DevKit. <CodeGroup> ```sh Shell theme={null} $ gem install appsignal Fetching appsignal 2.2.1 Installing appsignal 2.2.1 with native extensions Gem::InstallError: The 'appsignal' native gem requires installed build tools. Please update your PATH to include build tools or download the DevKit from 'http://rubyinstaller.org/downloads' and follow the instructions at 'http://github.com/oneclick/rubyinstaller/wiki/Development-Kit' ``` </CodeGroup> ### Microsoft Windows Subsystem for Linux <Warning> We do not provide support for the Microsoft Windows Subsystem for Linux. </Warning> The [Microsoft Windows Subsystem for Linux](https://docs.microsoft.com/en-us/windows/wsl/about) (WSL) is a layer between Microsoft Windows and a [Linux](#linux) distribution. This allows users to run certain GNU/Linux distributions, that are available in the Microsoft Store, on their Microsoft Windows computer. Running an app on WSL using an AppSignal integration will not cause any errors or build issues, as described in the [Microsoft Windows section](#microsoft-windows). Running AppSignal on WSL will work as well as the WSL supports it. Follow the steps for your [Linux distribution](#linux) on this page in the WSL environment to properly install the AppSignal dependencies, before installing AppSignal in your app. In our testing using the Ubuntu WSL, we've found that most AppSignal features will work, but we can't say how accurate the information gathered from it is. Some small differences between WSL's implementation and our Linux test setups, may cause odd behavior or inaccurately reporting of metrics. We do not actively test against WSL and cannot guarantee its successful operation. <u>We do not provide support for AppSignal on the WSL.</u> Not all AppSignal features will work on the WSL system, in our testing we've confirmed [host metrics](/metrics/host-metrics) for disks (usage and IO) do not work. Use the WSL system to test AppSignal's integration with your app in a development environment, but not do not use this setup in a production environment. Always test your app using AppSignal on a staging environment with a similar environment (Operating System) to the app's production environment first. [alpine linux]: https://alpinelinux.org/ [musl]: https://www.musl-libc.org/ [rust]: https://www.rust-lang.org/en-US/ [host-metrics]: /metrics/host-metrics.html [support]: mailto:support@appsignal.com # Public Status Page Source: https://docs.appsignal.com/uptime-monitoring/public-status-page You can use our public status pages to expose your uptime monitoring metrics to your users and to keep your users informed during your application's downtime. ## Set up <Tip> To set up a public status page **on a custom domain**, follow the instructions on the [Custom Domain](/uptime-monitoring/public-status-page/custom-domain) page **before** continuing with the instructions in this page. </Tip> To set up a new public status page, [navigate to "Uptime Pages"](https://appsignal.com/redirect-to/organization?to=status_pages) and click on the "Add status page" button. You can select any of your existing uptime monitors to be displayed on the public status page. <Tip> To set up a public status page, you must have already created an [Uptime Monitor](/uptime-monitoring/setup) in any of your applications. </Tip> When creating a public status page, you can choose a subdomain name for the public status page to be publicly available at, or you can choose a custom domain name. For example, if you choose the subdomain "my-app", your public status page will be available at `https://my-app.appsignal-status.com`. Once the subdomain is available, you can share it with your users so that they can see your application's current status. <Tip> It can take up to ten minutes for the public status page to be available at the subdomain. </Tip> <img alt="Screenshot of uptime monitoring page" /> ### Status page updates You can post a status update for your public status page by clicking on the "Add update" button. When posting a status update, you can set the status to **Investigating**, **Identified** or **Recovering** to signal that an incident has started or is still taking place. This will report that your application is currently down. Once your application's incident is over, use the **Resolved** state to let your users know that your application is back up. <img alt="Screenshot of uptime monitoring page" /> # Custom Domain Source: https://docs.appsignal.com/uptime-monitoring/public-status-page/custom-domain You can configure a custom domain for your application's Public Status Page. <Tip> You must follow the instructions on this page **before** the public status page is created. If you have already created a public status page, after following the instructions on this page, you will need to delete the status page and create it again. </Tip> To use custom status page URLs, you must set up a CNAME (Canonical Name) record in your domain's DNS (Domain Name System) records. How you add a new CNAME record will vary [depending on your DNS provider](#popular-dns-provider-documentation). The "Host" or "Name" setting of the CNAME must be set to the subdomain's name where you want the public status page to be accessible. For example, if you want the public status page to be accessible at `status.example.app`, you would set the "Host" or "Name" value to `status`. The "Value" setting must always be set to the following value: `cname.appsignal-status.com` Once you've added your new CNAME record, it may take several hours for the changes to take effect. Once the changes have replicated across the DNS network, you can create a public status page, setting the "Custom domain" value to the full domain name you want the public status page to be accessible at, including the subdomain (for example, `status.example.app`). <Tip> Currently, we do not support IPv6. You need to make sure the endpoint is reachable through IPv4. </Tip> ### Popular DNS Provider Documentation Below are links that take you to the CNAME-specific documentation of popular DNS providers. If your DNS provider is not listed, instructions should be available in the support section of their website. * [GoDaddy](https://www.godaddy.com/help/add-a-cname-record-19236) * [namecheap](https://www.namecheap.com/support/knowledgebase/article.aspx/9646/2237/how-to-create-a-cname-record-for-your-domain/) * [Domain.com](https://www.domain.com/help/article/dns-management-how-to-add-edit-and-delete-dns-records-video) * [Google Domains](https://support.google.com/a/answer/47283?hl=en) * [DreamHost](https://help.dreamhost.com/hc/en-us/articles/360035516812-Adding-custom-DNS-records) <Note> πŸ›Ÿ Need a hand? [Contact us](mailto:support@appsignal.com), and we'll help you get your Public Status Page custom domain set up. </Note> # Uptime monitoring Source: https://docs.appsignal.com/uptime-monitoring/setup With AppSignal uptime monitoring you can receive alerts when your application is down. We check your application from multiple regions across the world, and we will alert you when your application can't be reached from any of these regions. We also graph the performance of the endpoint you provide from different regions around the world. <img alt="Screenshot of uptime monitoring dashboard" /> ## Setup To setup a new uptime monitor check, click the "Add uptime monitor" button on the [Uptime Monitoring](https://appsignal.com/redirect-to/app?to=uptime_monitors) page. Provide the full URL (including `http://` or `https://`) of the page you'd like to check. Our servers will make a request to this URL every minute from multiple regions and report if the request fails or if the response status code is not in the `2xx` range. In order to receive notifications when your application is down, select a notification method. To prevent receiving alerts on small network hiccups, we recommend setting an alert warm-up period of at least one minute. You can set headers to be sent in the requests we perform against the URL you provide. This allows you to set authorization headers to enable the requests to go through. ## How it works We ping your applications from AWS Lambda workers that are executed from the following regions: We will request the given URL from the following regions: * Asia-Pacific (Seoul) * Europe (Frankfurt) * North America (N. Virginia) * South America (SΓ£o Paulo) There's a 30 second timeout to the connection. If your server does not respond within that time frame, we consider the application to be down. Note that if our requests to your application are failing from a single region, that doesn't necessarily mean your application is down. It could instead point to a networking issue between AWS Lambda and your endpoint. ### User Agent Our uptime monitoring requests to your application will set the `User-Agent` header as follows, where `<version>` is a version number like `1.0`: ```sh Shell theme={null} AppSignalBot/<version> (+https://appsignal.com) ``` This allows you to detect requests coming from AppSignal. ### IP Allowlisting We run our uptime checks on a serverless framework and have no control over what IP address will be used to make the request to your application. Therefore, we're unable to provide a list of IP addresses to allowlist. The URL to monitor must be publicly reachable from the open internet. ## Metrics For every uptime monitor check we create several metrics that you can use to create your own [custom graphs](/metrics/custom#graphing-custom-metrics) and set your own [anomaly detection triggers](/anomaly-detection#creating-and-configuring-triggers). These metrics will be tagged by the **region** from which the request was made, and the **name** of the uptime monitor check. The region tags are `asia-pacific`, `europe`, `north-america` and `south-america`. ### Error count The `uptime_monitor_error_count` metric is a counter that, for a given minute, will be set to zero if the request succeeded or to one if the request fails. <img alt="Screenshot of uptime monitoring error count custom metrics form" /> ### Endpoint performance The `uptime_monitor_duration` metric is a gauge that tracks the duration of the request for each region. This allows you to see if the latency to your servers is increasing. <img alt="Screenshot of uptime monitoring performance custom metrics form" /> ## Plans and Requests If the application serving the URL uses an AppSignal integration, our uptime monitor can use up a lot of your plan's monthly requests. We recommend setting up a dedicated health-check endpoint and configuring AppSignal to ignore requests to that endpoint so that they don't count toward your plan's limit. ### Example Here's an example of a health-check endpoint in Ruby on Rails. We make sure to hit all our external services, such as the database and Redis, something that might not happen on the homepage, ensuring all services are operational. <CodeGroup> ```ruby Ruby theme={null} # routes.rb resource :health_check, :only => :show ``` </CodeGroup> <CodeGroup> ```ruby Ruby theme={null} # health_checks_controller.rb class HealthChecksController < ApplicationController def show # Check MongoDB Account.mongo_client.command(:getLastError => 1) # Check Redis Redis.new.ping head 200 rescue Mongo::Error, Redis::CannotConnectError head 503 end end ``` </CodeGroup> Then, we configure AppSignal to ignore requests to that endpoint using [the `ignore_actions` configuration option](/ruby/configuration/options#option-ignore_actions): <CodeGroup> ```ruby Ruby theme={null} Appsignal.configure do |config| config.ignore_actions << "HealthChecksController#show" end ``` ```yaml YAML theme={null} default: &defaults ignore_actions: - HealthChecksController#show ``` </CodeGroup> # Your user account Source: https://docs.appsignal.com/user-account Whenever you use AppSignal your log in with your user account. A user can have access to one or more organizations that contain apps that are being monitored. ## Sign up When you are invited to an existing account or sign up, you can choose to sign up using GitHub or use an email / password combination. If you chose to sign up using an email / password combination, you can always link your GitHub account later on by visiting your [Profile & Settings](https://appsignal.com/users/edit) and scrolling down to GitHub section. ## Personal settings Once you're logged in you can navigate to your settings page by using the settings link at the top right of the screen. There are four personal setting screens. ### Personal In personal settings you can change your name and password. If you haven't linked your GitHub account during sign-up, you can still do so here. Connecting your GitHub account gives you additional features like direct links to commits and linked stack trace lines. You can also choose a theme for the AppSignal UI here. Switch the **Theme** toggle to **Dark** for a dark theme, **Light** to keep the default light theme, or **System** to follow your operating system's preference. ### Notifications You can have multiple email addresses associated with AppSignal. This could be useful if someone invites you on your personal email address while you prefer to use your company email address. It's also useful if you are part of multiple organizations within AppSignal. You can choose to have notifications sent to different email addresses per organization. <img alt="Email addresses" /> You can configure which email address AppSignal should use for notifications per organization. You can also choose whether you want to receive notifications per app. If you disable notifications you'll still be able to access the app. <img alt="Notifications" /> # Email addresses Source: https://docs.appsignal.com/user-account/email-addresses ## Change your primary email address The primary email address of your user account is the email address with which you sign in. It is not possible to sign in with secondary email addresses associated with your user account. To change your primary email address following these steps: 1. Log in to your account. 2. Visit [appsignal.com/users/notifications](https://appsignal.com/users/notifications) 1. Alternatively: In the top navigation bar click on "Profile & Settings" 2. On your profile page click "Notifications" in the sidebar navigation. 3. Add the email address that you want to use as a notification address. 4. Click on the "set as default" button for the email address you want to make your primary address. 5. The new email address will now receive a confirmation email to prove that you have access to this address. 6. Click on the link in the email you've received to make this email address your new primary email address.\ **Note**: Your previous primary email address will be remain primary until the new address is confirmed. # Two-factor authentication Source: https://docs.appsignal.com/user-account/two-factor-authentication AppSignal provides *two-factor authentication* (2FA) to add an extra level of security to your account. Besides using your email address and password, enabling 2FA requires you to enter a one-time password code whenever you sign in. The code is automatically generated by an application on your phone. <Warning> **Warning**: AppSignal is not able to help you gain access to your user account again if you lose your phone and haven't saved your backup codes. Please make sure you have your backup codes stored in a secure place. </Warning> ## Enabling two-factor authentication 1. Download an authenticator application on your phone. We recommend [Google Authenticator](https://support.google.com/accounts/answer/1066447?hl=en) for Android and iOS users. 2. Visit the [security page](https://appsignal.com/users/security) and click the "Enable two-factor authentication"-button. 3. Scan the QR code shown on the next page with your authenticator application on your phone. 4. Enter the six-digit code from the application and press "Enable two-factor authentication". 5. 2FA is now enabled. Don't forget to save the backup codes in a safe location. You can use them to sign into AppSignal if you ever lose your phone. ## Disabling two-factor authentication 1. Visit the [security page](https://appsignal.com/users/security) and click the "Disable two-factor authentication"-button. 2. You can now remove AppSignal from your authenticator application on your phone ## Regenerating backup codes You can use a backup code to sign into your account when you lose access to your phone. We show the backup codes once after enabling 2FA for your account. If you lose your backup codes, you can regenerate them on the security page. The newly generated backup codes invalidate and replace any existing ones. 1. Visit the [security page](https://appsignal.com/users/security) and click the "Regenerate backup codes"-button. 2. Save the backup codes in a safe location. You can use them to sign into AppSignal if you ever lose your phone. # Vector Source: https://docs.appsignal.com/vector AppSignal supports receiving metrics and logs from [Vector](https://vector.dev/). ## Configuration First set up your [Vector installation](https://vector.dev/docs/setup/quickstart/), with sources that receive input from other systems. Vector supports a multitude of data sources, such as Kubernetes, PostgreSQL, MongoDB and many more. See the [Vector source documentation](https://vector.dev/docs/reference/configuration/sources/) for more information on available sources. To send data from Vector sources to AppSignal, configure the AppSignal Vector sink in your Vector configuration. Add a new Vector sink with the type `appsignal`, configure the sources (inputs) from which to collect data, and include your [app-level Push API key](/appsignal/terminology#push-api-key). The app-level Push API key can be found in your app's [Push & Deploy settings](https://appsignal.com/redirect-to/app?to=api_keys\&key_tab=app). <CodeGroup> ```toml TOML theme={null} # vector.toml # Add this AppSignal sink section [sinks.appsignal] type = "appsignal" inputs = [ ... ] # Reference Vector sources or transforms here push_api_key = "Your app-level Push API key" ``` </CodeGroup> To send data to a different AppSignal application depending on its source, you can configure more than one AppSignal sink. Each sink can have different input sources and a different app-level push API key. You can read more about how to configure the AppSignal Vector Sink on the [Vector AppSignal sink documentation website](https://vector.dev/docs/reference/configuration/sinks/appsignal/). ## Metrics Metrics received from the AppSignal Vector Sink will be available in the [custom metrics](/metrics/custom) feature. AppSignal currently only supports the following [Vector metric event types](https://vector.dev/docs/about/under-the-hood/architecture/data-model/metric/): * Gauge * Counter * Distribution If a source sends other metrics types than listed below, those metrics are ignored. Custom metrics will require some manual setup. [Create a new dashboard](/metrics/dashboards) and add a graph using metrics received from Vector. Tags on metrics are converted into AppSignal metric tags and can be used to filter the metrics displayed in the graphs. An additional `vector_namespace` tag will be added, with the Vector metric's namespace as its value. See [Vector's documentation](https://vector.dev/docs/reference/configuration/sources/) for more information on each source's default value. Specified timestamps on metrics are currently ignored and the metric is reported for the time it was received. ### Magic dashboards AppSignal will automatically create dashboards when it detects metrics from the following Vector sources: * [PostgreSQL magic dashboard](/vector/postgresql) * [MongoDB magic dashboards](/vector/mongodb) ## Logs [AppSignal Logging](/logging) supports Vector [log events](https://vector.dev/docs/about/under-the-hood/architecture/data-model/log/). To view logs from Vector in our logging feature, first [create a new source](https://appsignal.com/redirect-to/app?to=logs/sources\&overlay=logSourceFormOverlay), for the platform "Vector", with the name `vector`. With every log line, Vector includes the `source_type` attribute. This is based on the name of the Vector log source. The `source_type` will be used to group tags in AppSignal logging, making it easier to find all logs from the same source. ## Tracing AppSignal does not support traces collected by Vector at this time. Please use one of our [language integrations](/#languages). # MongoDB Vector source Source: https://docs.appsignal.com/vector/mongodb Get more insights into the operation of your MongoDB database or cluster with our Vector MongoDB integration. [Vector](https://vector.dev) has a [MongoDB source][source] that collects metrics from your MongoDB instances. When these MongoDB metrics are sent to AppSignal, the metrics from this Vector source will be shown in our MongoDB automatic dashboards. ## Configuration <Tip> If you've not set up Vector yet, please see the [Vector configuration section](/vector#configuration) for more information, such as which Push API key to use. </Tip> To send MongoDB data to AppSignal using Vector, you will need to configure the MongoDB source and AppSignal sink in your Vector configuration. We'll be using the TOML configuration file as an example. 1. Add a new source of the [`mongodb_metrics` source][source] type to your configuration file. The name of the source is the part following the dot in `sources.mongodb`, not the `mongodb_metrics` type. <CodeGroup> ```toml TOML theme={null} [sources.mongodb] type = "mongodb_metrics" ``` </CodeGroup> 2. Configure the source's `endpoints` option with the MongoDB URL for your database. Replace the variables (`$VARIABLE_NAME`) with the values for your database, or pass them as environment variables. If running a database cluster, you should specify each member of the cluster as an endpoint. <CodeGroup> ```toml TOML theme={null} [sources.mongodb] type = "mongodb_metrics" endpoints = ["$MONGODB_URL"] # or, if running a MongoDB cluster: # endpoints = ["$MONGODB_URL_1", "$MONGODB_URL_2", "$MONGODB_URL_3"] ``` </CodeGroup> 3. Update `inputs` in the `appsignal` sink to include the name of the `mongodb_metrics` source: <CodeGroup> ```toml TOML theme={null} [sinks.appsignal] inputs = ["mongodb"] # Other config ``` </CodeGroup> Shown below is an example `vector.toml` configuration file. Your [Vector configuration method][vector config] may be different. <CodeGroup> ```toml TOML theme={null} [sources.mongodb] type = "mongodb_metrics" endpoints = ["$MONGODB_URL"] [sinks.appsignal] type = "appsignal" inputs = ["mongodb"] push_api_key = "Your app-level Push API key" ``` </CodeGroup> [source]: https://vector.dev/docs/reference/configuration/sources/mongodb_metrics/ [vector config]: https://vector.dev/docs/reference/configuration/ ## Dashboards From your MongoDB instances' metrics, we'll automatically set up several dashboards. ### Status dashboard The Status dashboard focuses on the overall health and activity of your MongoDB instances. <img alt="Status dashboard" /> It will report graphs for memory usage, network usage, document operations and open connections. This dashboard allows you to quickly spot what's impacting your database or your application, such as a drop in database connections or an increase in memory usage. ### WiredTiger dashboard The WiredTiger dashboard provides an in-depth view into the internals of the MongoDB database engine. <img alt="WiredTiger dashboard" /> It will report graphs for journal and block manager operations, the amount of bytes read and written from disk, the amount of data in the cache, and the amount of in-progress transactions. If you're dealing with a hard-to-track issue, such as an unexpected drop in database performance, these graphs can provide clues as to what the underlying cause is. ### Replication dashboard The Replication dashboard provides a view into the internals of the MongoDB cluster replication system. This dashboard will only appear if you are running a MongoDB cluster. <img alt="Replication dashboard" /> It will report graphs for the amount of network usage dedicated to replication, the size of the replication buffers, and the amount of replication operations pending execution. This dashboard can help investigate issues related to the health of your cluster, such as stale reads and replication delays. # PostgreSQL Vector source Source: https://docs.appsignal.com/vector/postgresql Get more insights into the operation of your PostgreSQL databases with our Vector PostgreSQL integration. [Vector](https://vector.dev) has a [PostgreSQL source][source] that collects metrics from PostgreSQL databases. When these PostgreSQL metrics are sent to AppSignal, the metrics from this Vector source will be shown in our PostgreSQL automatic dashboard. This dashboard will tell you more about: * how many records were selected, inserted, updated and deleted. * how many transactions were committed and rolled back. * how many deadlocks were detected. * how many temporary files were written during the operation of the database. ## Configuration <Tip> If you've not set up Vector yet, please see the [Vector configuration section](/vector#configuration) for more information, such as which Push API key to use. </Tip> To send Vector PostgreSQL data to AppSignal you need to configure the PostgreSQL source and AppSignal sink in your Vector configuration. We'll be using the TOML configuration file as an example. 1. Add a new source of the [`postgresql_metrics` source][source] type to your configuration file. The name of the source is the part following the dot in `sources.postgresql`, not the `postgresql_metrics` type. <CodeGroup> ```toml TOML theme={null} [sources.postgresql] type = "postgresql_metrics" ``` </CodeGroup> 2. Configure the source's `endpoints` option with the PostgreSQL connection string for your database. Replace the variables (`$VARIABLE_NAME`) with the values for your database, or pass them as environment variables. <CodeGroup> ```toml TOML theme={null} [sources.postgresql] type = "postgresql_metrics" endpoints = ["postgresql://$POSTGRES_USER:$POSTGRES_PASSWORD@postgres:5432/$POSTGRES_DB"] ``` </CodeGroup> 3. Update `inputs` in the `appsignal` sink to include the name of the `postgresql_metrics` source: <CodeGroup> ```toml TOML theme={null} [sinks.appsignal] inputs = ["postgresql"] # Other config ``` </CodeGroup> Shown below is an example `vector.toml` configuration file. Your [Vector configuration method][vector config] may be different. <CodeGroup> ```toml TOML theme={null} [sources.postgresql] type = "postgresql_metrics" endpoints = ["postgresql://$POSTGRES_USER:$POSTGRES_PASSWORD@postgres:5432/$POSTGRES_DB"] [sinks.appsignal] type = "appsignal" inputs = ["postgresql"] push_api_key = "Your app-level Push API key" ``` </CodeGroup> [source]: https://vector.dev/docs/reference/configuration/sources/postgresql_metrics/ [vector config]: https://vector.dev/docs/reference/configuration/ # Vercel Logs Source: https://docs.appsignal.com/vercel/logs AppSignal can automatically ingest Vercel logs. This setup requires an additional authorization step outlined in this step-by-step documentation. Ensure you have access to your Vercel login credentials before creating a new Vercel logging source. ## Creating a Vercel Log Source Our configuration documentation covers log sources in greater detail. To create a new log source navigate to the Logging page in the AppSignal application and click on the Add log source button in the top right of the page. A pop-up will appear, prompting you to name your source. It's important to give your source a descriptive name like Redis or MongoDB so that you can successfully query these logs in the future. Once you've named your source, select "Vercel" as your log source's platform. A notification will appear below the source dropdown asking you to authorize AppSignal via Vercel. Click "Authenticate with Vercel". Vercel will open in a new browser tab. <img alt="Screenshot of Add new source pop-up" /> The pop-up contains the following fields: * **Source name** β€” a descriptive label for your source (e.g. "Vercel"). * **Choose your platform** β€” select "Vercel". * **Authenticate with Vercel** β€” required to use this source. * **Log format** β€” shown further down the form after authenticating; choose how AppSignal parses your log messages (e.g. `plaintext` or `JSON`). * **Create a new view with this source** β€” optional; opens a logging view tied to this source after creation. Vercel will ask you to add the AppSignal integration. Click "Add Integration". <img alt="Screenshot of Logging Sources page" /> Next, choose which Vercel Account you want to add AppSignal to. <img alt="Screenshot of Logging Sources page" /> Follow the steps on Vercel until you get to the final screen. Here you need to click "Add Integration": <img alt="Screenshot of Logging Sources page" /> Next, you will need to select which AppSignal organization you want to link Vercel to. <img alt="Screenshot of Logging Sources page" /> Now you can return to AppSignal. AppSignal will check with Vercel every 30 seconds to see if it has been authorized. Do not save your log source until authorization has completed, and display a dropdown of your Vercel projects: <img alt="Screenshot of Logging Sources page" /> <Note> πŸ›Ÿ If you get stuck on this step, please [get in touch](mailto:support@appsignal.com) with us, and we'll help you get your Vercel logs flowing! </Note> Select the project you wish to ingest logs from and click "Add log source" Once your new log source has been created, logs should appear in AppSignal. If you still cannot see any logs, please [contact us](mailto:support@appsignal.com) for support. # Vercel Source: https://docs.appsignal.com/vercel/overview AppSignal provides observability for applications deployed on Vercel. With AppSignal you can: * [**Collect traces and metrics**](/vercel/traces) from your application and Vercel's infrastructure; * Ingest [**application logs**](/vercel/logs); * Track Web Vitals and understand user experience using [**Speed Insights**](/vercel/speed-insights). # Speed Insights Source: https://docs.appsignal.com/vercel/speed-insights Vercel Drains provide support for [Web Vitals](https://web.dev/articles/vitals) through the Speed Insights drain. These metrics can serve as signals for delivering great user experience on the web. To start receiving Web Vitals in AppSignal, enable **Speed Insights**, add `@vercel/speed-insights` package to your project and create a **Speed Insights drain**. ## 1. Enable Speed Insights From your organisation's page, click on the project that you would like to enable the Speed Insights for. Then click on the **Speed Insights** tab, where you will be presented with an **Enable Speed Insights** dialog. <img alt="Screenshot of "Enable Speed Insights" dialog in the Vercel UI" /> Click on **Purchase** to enable **Speed Insights**. ## 2. Add `@vercel/speed-insights` to your project Add `@vercel/speed-insights` package to your project and include `<SpeedInsights />` component in your app. <CodeGroup> ```shell Shell theme={null} npm install @vercel/speed-insights ``` </CodeGroup> This will add a script to the page and start tracking Web Vitals. For more detailed instructions head over to [Vercel documentation page](https://vercel.com/docs/speed-insights/quickstart#add-the-speedinsights-component-to-your-app). ## 3. Configure Speed Insights drain From a Vercel project navigate to **Settings > Drains** page and click on **Add Drain**. <img alt="Screenshot of "Add Drain" step in the Vercel UI" /> Select **Speed Insights** as the drain type and click **Next**. <img alt="Screenshot of "Add Drain" step in the Vercel UI" /> Add a descriptive name for the drain, such as 'AppSignal speed insights drain'. The **Specific projects** option along with your project should be pre-selected in the **Projects** section. If it is not, make sure to only select the project that you enabled Speed Insights for. Click **Next**. <img alt="Screenshot of "Configure drain" step in the Vercel UIt" /> For **destination** enter the following URL replacing `<api_key>` with your AppSignal app-level push API key, which can be found in [App settings](https://appsignal.com/redirect-to/app?to=api_keys\&key_tab=app): <CodeGroup> ```plaintext Text theme={null} https://appsignal-endpoint.net/metrics/speed-insights?api_key=<api_key> ``` </CodeGroup> <Note> You can find more information about **AppSignal API keys** in the AppSignal API's [Public Endpoint Authentication section](https://docs.appsignal.com/api/public-endpoint.html#authentication). </Note> Pressing **Test** will send a test trace to AppSignal. Click **Create Drain**. On successful setup, a new [magic dashboard](https://blog.appsignal.com/2019/03/27/magic-dashboards.html) will be created for you with Next.js Web Vitals. # Traces from Vercel applications Source: https://docs.appsignal.com/vercel/traces When deploying applications or functions on Vercel, you can send telemetry data to AppSignal in one of two ways: 1. [Using Vercel's traces drain](#using-the-traces-drain). In addition to forwarding data collected by Vercel's OpenTelemetry instrumentation package, this will also provide visibility into Vercel's infrastructure, such as Vercel functions and edge network. 2. [Using Vercel's OpenTelemetry instrumentation package](#using-the-instrumentation-package). Make sure you [have a hosted collector URL](/collector/hosted-vs-self-hosted#hosted-collector) before proceeding with these instructions. ## Using the traces drain To forward traces from Vercel to AppSignal using the traces drain, you need to set up a traces drain in your Vercel project settings. It is also recommended to install [Vercel's OpenTelemetry instrumentation package](https://vercel.com/docs/tracing/instrumentation) in your application to capture telemetry data from your application. Using Vercel's traces drain requires a Vercel plan on which drains are available. See [Vercel's drains documentation](https://vercel.com/docs/drains) for more information on available plans and pricing. ### Set up a traces drain From the Vercel dashboard, navigate to your project and go to the **Settings > Drains** section. Click on **Add Drain** and select **Traces** as the drain type. <img alt="Screenshot of "Add Drain" step in the Vercel UI" /> When asked which projects should send data using this drain, make sure to only select this project. <img alt="Screenshot of "Configure drain" step in the Vercel UI" /> Under **Configure the destination**, select **Custom** endpoint and enter the URL of your AppSignal collector's OTLP endpoint, adding `/v1/traces` at the end: <CodeGroup> ```plaintext title="Example URL" theme={null} https://your-appsignal-collector-host.com/v1/traces ``` </CodeGroup> In the **Encoding** dropdown, select **Protobuf**. Enable **Custom Headers** and add the following headers to authenticate with AppSignal, replacing the placeholder values with your application's information as shown in AppSignal. Your Push API key can be found in the [App settings](https://appsignal.com/redirect-to/app?to=info). <CodeGroup> ```yaml Custom Headers theme={null} AppSignal-Config-Name: <your-app-name> AppSignal-Config-Environment: <your-app-environment> AppSignal-Config-PushApiKey: <your-appsignal-push-api-key> AppSignal-Config-Revision: vercel AppSignal-Config-LanguageIntegration: nodejs OpenTelemetry-HostName: vercel ``` </CodeGroup> Pressing **Test** will send a test trace to AppSignal and save the drain on success. ### Install and configure the instrumentation package Use npm to add Vercel's OpenTelemetry instrumentation package and the OpenTelemetry API to your application's dependencies: <CodeGroup> ```shell Shell theme={null} npm install @opentelemetry/api @vercel/otel ``` </CodeGroup> If you're using Next.js, add the `instrumentation.ts` file to your application. It must be placed in the root directory of the project (or inside the `src` folder if using one). If you're using other frameworks or Vercel functions, make sure that this code is loaded early in the execution process to properly capture OpenTelemetry data. <CodeGroup> ```typescript TypeScript theme={null} import { registerOTel } from "@vercel/otel"; export function register() { registerOTel({ serviceName: "My service", }); } ``` </CodeGroup> Update the service name to a recognizable name for your application. ## Using the instrumentation package To send telemetry data to AppSignal using [Vercel's OpenTelemetry instrumentation package](https://vercel.com/docs/tracing/instrumentation), you need to install and configure the package in your application. ### Install the OpenTelemetry packages Use npm to add Vercel's OpenTelemetry instrumentation package, the OpenTelemetry SDK and the OTLP exporter to your application's dependencies: <CodeGroup> ```shell Shell theme={null} npm install @opentelemetry/api \ @opentelemetry/sdk-metrics \ @opentelemetry/exporter-trace-otlp-proto \ @opentelemetry/exporter-metrics-otlp-proto \ @vercel/otel ``` </CodeGroup> ### Configure OpenTelemetry in your application If you're using Next.js, add the `instrumentation.ts` file to your application. It must be placed in the root directory of the project (or inside `src` folder if using one). If you're using other frameworks or Vercel functions, make sure that this code is loaded early in the execution process to properly capture OpenTelemetry data. <CodeGroup> ```typescript TypeScript theme={null} import { registerOTel } from "@vercel/otel"; import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-proto"; import { OTLPMetricExporter } from "@opentelemetry/exporter-metrics-otlp-proto"; import { PeriodicExportingMetricReader } from "@opentelemetry/sdk-metrics"; const collectorHost = "https://your-appsignal-collector-host.com"; export function register() { registerOTel({ serviceName: "My service", traceExporter: new OTLPTraceExporter({ url: `${collectorHost}/v1/traces`, }), metricReader: new PeriodicExportingMetricReader({ exportIntervalMillis: 1000, exporter: new OTLPMetricExporter({ url: `${collectorHost}/v1/metrics`, }), }), attributes: { "appsignal.config.name": "My app", "appsignal.config.environment": "production", "appsignal.config.revision": "1", "appsignal.config.language_integration": "nodejs", "appsignal.config.push_api_key": "0000-0000-0000-0000", "host.name": "vercel", }, }); } ``` </CodeGroup> ## Test the integration Once you have completed one of the integration options above, deploy your application to Vercel (or run a preview deployment) and test if you see data arrive in AppSignal. Check the ["Errors > Issue list"](https://appsignal.com/redirect-to/app?to=exceptions) and ["Performance > Traces"](https://appsignal.com/redirect-to/app?to=performance/traces) page specifically. If after following our installation instructions you still don't see data in AppSignal, [let us know](mailto:support@appsignal.com?subject=OpenTelemetry%20issue) and we'll help you finalize your OpenTelemetry installation! # AppSignal Wrap for process monitoring Source: https://docs.appsignal.com/wrap AppSignal provides `appsignal-wrap`, a tool to monitor any processes running in your server, such as your cron jobs, your database server, or any other processes pertaining to your application. The `appsignal-wrap` tool seamlessly integrates with AppSignal's cron and heartbeat process monitors, logging, and error reporting. It can be used to monitor any process running on your servers, regardless of the language or framework it's written in. ### AppSignal Wrap helps answer questions like: <div> <span> <Icon icon="check" /> </span> <span>Is my database process up and running?</span> </div> <div> <span> <Icon icon="check" /> </span> <span>Is my cron job running on time?</span> </div> <div> <span> <Icon icon="check" /> </span> <span>What went wrong with my backup script?</span> </div> <div> <span> <Icon icon="check" /> </span> <span>Did my application server fail to start?</span> </div> ### Core appsignal-wrap features After installing `appsignal-wrap`, you can use the tool to start processes you want to monitor. The `appsignal-wrap` tool will then: <div> <span> <Icon icon="line-columns" /> </span> <span>Report the standard output and standard error of the process, as logs that you can filter and query on [AppSignal Logging](/logging).</span> </div> <div> <span> <Icon icon="square-check" /> </span> <span>Send [cron process monitors](/check-ins) to report that the process has started and finished successfully, or [heartbeat process monitors](/check-ins) to keep track of its uptime.</span> </div> <div> <span> <Icon icon="siren-on" /> </span> <span>Report failure exit statuses as errors to AppSignal.</span> </div> ## Installation The easiest way to install `appsignal-wrap` is to run the following command: <CodeGroup> ```bash Bash theme={null} curl -sSL https://github.com/appsignal/appsignal-wrap/releases/latest/download/install.sh | sudo sh ``` </CodeGroup> The command will automatically download the latest release of `appsignal-wrap` for your OS (operating system) and architecture, and install it to your server's `$PATH`. Both Linux and macOS are supported, in the x86 64-bit (Intel) and ARM 64-bit (Apple Silicon) architectures. Alpine Linux is also supported through our `musl`-enabled builds for both architectures. Alternatively, you can download the latest release from the [GitHub releases page](https://github.com/appsignal/appsignal-wrap/releases/latest/) for your operating system and architecture, and install it manually to your server's `$PATH`. ## Usage To monitor a process with `appsignal-wrap`, you pass the command that you want to monitor as the last argument to `appsignal-wrap`. For example: <CodeGroup> ```sh Shell theme={null} export APPSIGNAL_APP_PUSH_API_KEY=[APP_LEVEL_API_KEY] appsignal-wrap [NAME] -- [COMMAND] ``` </CodeGroup> In the above example, `[NAME]` is the name that you want to use to identify the process in AppSignal, and `[COMMAND]` is the command that you want to monitor. Both the name and the command are required. For example: <CodeGroup> ```sh Shell theme={null} appsignal-wrap backup-script -- bash /var/app/backup.sh ``` </CodeGroup> You'll need an AppSignal app-level API key, which you can find in the ["Push & Deploy"](https://appsignal.com/redirect-to/app?to=api_keys\&key_tab=app) settings of your AppSignal app. You can provide it to `appsignal-wrap` as the argument to the `--api-key` command-line option, or as the `APPSIGNAL_APP_PUSH_API_KEY` environment variable. By default, `appsignal-wrap` will report the standard output and standard error of the process as logs to AppSignal, and report any failure exit statuses to AppSignal as errors. <span /> ## Process Monitoring <Tip> [Read our Process Monitoring documentation](/check-ins) for more information on how AppSignal Process Monitoring works. </Tip> By default, `appsignal-wrap` will not send any process monitor events. You can use the `--cron` or `--heartbeat` command-line options to enable cron or heartbeat process monitors respectively. The `appsignal-wrap` tool will use the name provided as the first argument as the process monitor identifier. For example, to report cron process monitor events with `backup-script` as the process monitor identifier: <CodeGroup> ```sh Shell theme={null} appsignal-wrap backup-script --cron -- bash /var/app/backup.sh ``` </CodeGroup> ### Cron process monitors When using `--cron` to send cron process monitors, `appsignal-wrap` will send a start cron process monitor event when the process starts, and a finish cron process monitor event if the process finishes successfully. If the process exits with a failure exit status, `appsignal-wrap` will not send a finish cron process monitor event. ### Heartbeat process monitors When using `--heartbeat` to send heartbeat process monitors, `appsignal-wrap` will send heartbeat process monitor events continuously during the lifetime of the process. ### Custom identifier To send process monitor events to AppSignal with an identifier different from the name provided as the first argument, you can pass a different identifier as an argument to the `--cron` or `--heartbeat` command-line options. For example: <CodeGroup> ```sh Shell theme={null} appsignal-wrap backup --cron daily-backup -- bash /var/app/backup.sh ``` </CodeGroup> In the above example, `appsignal-wrap` will send cron process monitor events with `daily-backup` as the process monitor identifier, but will still use `backup` as the name to identify the process when reporting logs and errors. ## Logging By default, `appsignal-wrap` will send both the standard output and standard error of the process it monitors as logs to AppSignal. The logs will appear under the "application" source, and the name provided as the first argument will be used as the log group. ### Disable logging To disable sending either the standard output or standard error as logs, you can use the `--no-stdout` or `--no-stderr` command-line options respectively. To disable sending logs altogether, you can use the `--no-log` command-line option. ### Custom log group To send logs as a different log group, you can pass it as an argument to the `--log` command-line option. For example: <CodeGroup> ```sh Shell theme={null} appsignal-wrap mysql --log db -- mysqld ``` </CodeGroup> In the above example, `appsignal-wrap` will use `db` as the log group when sending logs to AppSignal, but will still use `mysql` as the name to identify the process when reporting process monitors and errors. ### Custom log source To send logs to a different log source, you can pass the log source's API key, which you obtain when [creating a log source](https://docs.appsignal.com/logging/configuration.html#creating-a-log-source), as an argument to the `--log-source` command-line option, or as the `APPSIGNAL_LOG_SOURCE_API_KEY` environment variable. For example: <CodeGroup> ```sh Shell theme={null} export APPSIGNAL_LOG_SOURCE_API_KEY=[LOG_SOURCE_API_KEY] appsignal-wrap mysql -- mysqld ``` </CodeGroup> ## Error reporting By default, `appsignal-wrap` will report any failure exit statuses of the process it monitors as errors to AppSignal. The errors will be grouped by the name provided as the first argument. ### Disable error reporting To disable reporting errors entirely, you can use the `--no-error` command-line option. ### Output in error messages When reporting errors to AppSignal, `appsignal-wrap` will include the last few lines of the standard output and standard error of the process as the error message. Using the `--no-stdout` or `--no-stderr` command-line options will prevent the standard output or standard error from being included in the error message. Using both options will prevent any logs from being included in the error message. ### Custom error grouping To group errors differently, you can pass a different name as an argument to the `--error` command-line option. For example: <CodeGroup> ```sh Shell theme={null} appsignal-wrap backup --error user-backup -- bash /var/app/backup.sh --only-users ``` </CodeGroup> In the above example, `appsignal-wrap` will report errors with `user-backup` as the error group, but will still use `backup` as the name to identify the process when reporting logs and process monitors. ### Application revision <Compatibility /> If a revision is provided using the `--revision` flag or the `APPSIGNAL_REVISION` environment variable, errors will be grouped with the deployment for that revision. ## Process behavior The `appsignal-wrap` tool aims to be *transparent* -- that is, running some command using `appsignal-wrap` should have the same behavior as running that same command by itself. <Note> After the monitored process finishes, `appsignal-wrap` will wait for a short period of time *(usually one second or less)* before exiting, in order to ensure that all logs and process monitors are sent to AppSignal. If invoking `appsignal-wrap` in a loop, the delay caused by this wait may cause the loop to run slower than expected. </Note> ### Environment variables The process automatically inherits the environment variables of the `appsignal-wrap` parent process. ### Exit status If the process it monitors exits with an exit code, `appsignal-wrap` will exit with the same failure exit code. If the process it monitors is terminated by a signal, `appsignal-wrap` will exit with a failure exit code of `128 + signal`, where `signal` is the number representing the signal that caused the process to terminate. The signal that this number represents is operating system-specific. ### Input and output The process automatically inherits its standard input descriptor from the `appsignal-wrap` parent process. In addition to reporting them to AppSignal, the standard output and standard error of the process are piped to the standard output and standard error of the `appsignal-wrap` parent process. When using `--no-stdout` or `--no-stderr`, the process automatically inherits the standard output or standard error descriptor, respectively, of the `appsignal-wrap` parent process. This means that you can use `appsignal-wrap` in a pipeline, or redirect its output to a file, for example: <CodeGroup> ```sh Shell theme={null} # Without monitoring grep "active" customers.csv \ | python /var/app/import.py \ > /var/log/import.log # With monitoring grep "active" customers.csv \ | appsignal-wrap import-customers -- python /var/app/import.py \ > /var/log/import.log ``` </CodeGroup> ### Signals When the `appsignal-wrap` process receives a signal that can be handled, it will forward it to the process it monitors. For example, sending a `SIGTERM` signal to the `appsignal-wrap` parent process will cause the process it monitors to receive a `SIGTERM` signal. When the `appsignal-wrap` parent process receives a signal that cannot be handled, such as `SIGKILL` and `SIGSTOP`, or if it unexpectedly crashes, a `SIGTERM` signal will be sent to the process it monitors.