-
Notifications
You must be signed in to change notification settings - Fork 1.5k
N8N integration #21835
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
N8N integration #21835
Changes from all commits
10999db
08e8203
6c7ada3
abce4d6
8a35317
020e48f
a798858
b8d7c78
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| # CHANGELOG - n8n | ||
|
|
||
| <!-- towncrier release notes start --> | ||
|
|
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,60 @@ | ||||||
| # Agent Check: n8n | ||||||
|
|
||||||
| ## Overview | ||||||
|
|
||||||
| This check monitors [n8n][1] through the Datadog Agent. | ||||||
|
|
||||||
| Include a high level overview of what this integration does: | ||||||
| - What does your product do (in 1-2 sentences)? | ||||||
| - What value will customers get from this integration, and why is it valuable to them? | ||||||
| - What specific data will your integration monitor, and what's the value of that data? | ||||||
|
|
||||||
| ## Setup | ||||||
|
|
||||||
| Follow the instructions below to install and configure this check for an Agent running on a host. For containerized environments, see the [Autodiscovery Integration Templates][3] for guidance on applying these instructions. | ||||||
|
|
||||||
| ### Installation | ||||||
|
|
||||||
| The n8n check is included in the [Datadog Agent][2] package. | ||||||
| No additional installation is needed on your server. | ||||||
|
|
||||||
| ### Configuration | ||||||
|
|
||||||
| 1. Edit the `n8n.d/conf.yaml` file, in the `conf.d/` folder at the root of your Agent's configuration directory to start collecting your n8n performance data. See the [sample n8n.d/conf.yaml][4] for all available configuration options. | ||||||
|
|
||||||
| 2. [Restart the Agent][5]. | ||||||
|
|
||||||
| ### Validation | ||||||
|
|
||||||
| [Run the Agent's status subcommand][6] and look for `n8n` under the Checks section. | ||||||
|
|
||||||
| ## Data Collected | ||||||
|
|
||||||
| ### Metrics | ||||||
|
|
||||||
| See [metadata.csv][7] for a list of metrics provided by this integration. | ||||||
|
|
||||||
| ### Events | ||||||
|
|
||||||
| The n8n integration does not include any events. | ||||||
|
|
||||||
| ### Service Checks | ||||||
|
|
||||||
| The n8n integration does not include any service checks. | ||||||
|
|
||||||
| See [service_checks.json][8] for a list of service checks provided by this integration. | ||||||
|
|
||||||
| ## Troubleshooting | ||||||
|
|
||||||
| Need help? Contact [Datadog support][9]. | ||||||
|
|
||||||
|
|
||||||
| [1]: **LINK_TO_INTEGRATION_SITE** | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| [2]: https://app.datadoghq.com/account/settings/agent/latest | ||||||
| [3]: https://docs.datadoghq.com/containers/kubernetes/integrations/ | ||||||
| [4]: https://github.com/DataDog/integrations-core/blob/master/n8n/datadog_checks/n8n/data/conf.yaml.example | ||||||
| [5]: https://docs.datadoghq.com/agent/configuration/agent-commands/#start-stop-and-restart-the-agent | ||||||
| [6]: https://docs.datadoghq.com/agent/configuration/agent-commands/#agent-status-and-information | ||||||
| [7]: https://github.com/DataDog/integrations-core/blob/master/n8n/metadata.csv | ||||||
| [8]: https://github.com/DataDog/integrations-core/blob/master/n8n/assets/service_checks.json | ||||||
| [9]: https://docs.datadoghq.com/help/ | ||||||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,44 @@ | ||||||
| name: n8n | ||||||
| files: | ||||||
| - name: n8n.yaml | ||||||
| options: | ||||||
| - template: init_config | ||||||
| options: | ||||||
| - template: init_config/default | ||||||
| - template: instances | ||||||
| options: | ||||||
| - template: instances/openmetrics | ||||||
| overrides: | ||||||
| openmetrics_endpoint.required: true | ||||||
| openmetrics_endpoint.hidden: false | ||||||
| openmetrics_endpoint.display_priority: 1 | ||||||
| openmetrics_endpoint.value.example: http://localhost:5678 | ||||||
| openmetrics_endpoint.description: | | ||||||
| Endpoint exposing the n8n's metrics in the OpenMetrics format. For more information refer to: | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| https://docs.n8n.io/hosting/logging-monitoring/monitoring/ | ||||||
| https://docs.n8n.io/hosting/configuration/environment-variables/endpoints/ | ||||||
| raw_metric_prefix.description: | | ||||||
| The prefix prepended to all metrics from n8n. | ||||||
| If not set, the default prefix will be used. | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| The default prefix is 'n8n'. | ||||||
| If you are using a custom prefix in n8n through N8N_METRICS_PREFIX, you can set it here. | ||||||
| raw_metric_prefix.value: | ||||||
| display_default: n8n | ||||||
| type: string | ||||||
| example: n8n | ||||||
| raw_metric_prefix.hidden: false | ||||||
| - name: server_port | ||||||
| description: | | ||||||
| The port exposing the HTTP Endpoint of the N8N API. | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| value: | ||||||
| display_default: 5678 | ||||||
| type: integer | ||||||
| - template: logs | ||||||
| example: | ||||||
| - type: file | ||||||
| path: /var/log/n8n/*.log | ||||||
| source: n8n | ||||||
| service: <SERVICE> | ||||||
| - type: docker | ||||||
| source: n8n | ||||||
| service: <SERVICE> | ||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| { | ||
| "title": "N8N Overview Dashboard", | ||
| "description": "N8N Overview Dashboard", | ||
| "widgets": [], | ||
| "template_variables": [], | ||
| "layout_type": "ordered", | ||
| "notify_list": [], | ||
| "reflow_type": "fixed" | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| [ | ||
| { | ||
| "agent_version": "7.75.0", | ||
| "integration": "n8n", | ||
| "check": "n8n.openmetrics.health", | ||
| "statuses": ["ok", "critical"], | ||
| "groups": [], | ||
| "name": "n8n OpenMetrics Health", | ||
| "description": "Returns `CRITICAL` if the check cannot access the metrics endpoint. Returns `OK` otherwise." | ||
| }, | ||
| { | ||
| "agent_version": "7.75.0", | ||
| "integration": "n8n", | ||
| "check": "n8n.health.status", | ||
| "statuses": ["ok", "critical"], | ||
| "groups": [], | ||
| "name": "n8n Health Status", | ||
| "description": "Returns `CRITICAL` if the health check endpoint returns an unhealthy status. Returns `OK` otherwise." | ||
| }, | ||
| { | ||
| "agent_version": "7.75.0", | ||
| "integration": "n8n", | ||
| "check": "n8n.readiness.status", | ||
| "statuses": ["ok", "critical"], | ||
| "groups": [], | ||
| "name": "n8n Readiness Status", | ||
| "description": "Returns `CRITICAL` if the readiness check endpoint returns an unready status. Returns `OK` otherwise." | ||
| } | ||
| ] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| Initial Release |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| # (C) Datadog, Inc. 2025-present | ||
| # All rights reserved | ||
| # Licensed under a 3-clause BSD style license (see LICENSE) | ||
| __version__ = '0.0.1' |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| # (C) Datadog, Inc. 2025-present | ||
| # All rights reserved | ||
| # Licensed under a 3-clause BSD style license (see LICENSE) | ||
| from .__about__ import __version__ | ||
| from .check import N8nCheck | ||
|
|
||
| __all__ = ['__version__', 'N8nCheck'] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,99 @@ | ||
| # (C) Datadog, Inc. 2025-present | ||
| # All rights reserved | ||
| # Licensed under a 3-clause BSD style license (see LICENSE) | ||
|
|
||
| from urllib.parse import urljoin, urlparse # noqa: F401 | ||
|
|
||
| from datadog_checks.base import AgentCheck, OpenMetricsBaseCheckV2 | ||
| from datadog_checks.n8n.metrics import METRIC_MAP | ||
|
|
||
| DEFAULT_READY_ENDPOINT = '/healthz/readiness' | ||
| DEFAULT_HEALTH_ENDPOINT = '/healthz' | ||
| DEFAULT_VERSION_ENDPOINT = '/rest/settings' | ||
|
|
||
|
|
||
| class N8nCheck(OpenMetricsBaseCheckV2): | ||
| __NAMESPACE__ = 'n8n' | ||
| DEFAULT_METRIC_LIMIT = 0 | ||
|
|
||
| def __init__(self, name, init_config, instances=None): | ||
| super(N8nCheck, self).__init__( | ||
| name, | ||
| init_config, | ||
| instances, | ||
| ) | ||
| self.openmetrics_endpoint = self.instance["openmetrics_endpoint"] | ||
| self.tags = self.instance.get('tags', []) | ||
| self._ready_endpoint = DEFAULT_READY_ENDPOINT | ||
| self._health_endpoint = DEFAULT_HEALTH_ENDPOINT | ||
| self._version_endpoint = DEFAULT_VERSION_ENDPOINT | ||
| # Get the N8N API port if specified, otherwise use the default 5678. | ||
| self.server_port = str(self.instance.get('server_port', 5678)) | ||
| self.raw_metric_prefix = self.instance.get('raw_metric_prefix', 'n8n') | ||
|
|
||
| def get_default_config(self): | ||
| # If raw_metric_prefix is 'n8n', metrics start with 'n8n' | ||
| if self.raw_metric_prefix == 'n8n': | ||
| namespace = 'n8n' | ||
| else: | ||
| namespace = f'n8n.{self.raw_metric_prefix}' | ||
|
|
||
| return {'namespace': namespace, 'metrics': [METRIC_MAP]} | ||
HadhemiDD marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| @AgentCheck.metadata_entrypoint | ||
| def _submit_version_metadata(self): | ||
| endpoint = urljoin(self.openmetrics_endpoint, self._version_endpoint) | ||
| response = self.http.get(endpoint) | ||
|
|
||
| if response.ok: | ||
| data = response.json() | ||
| version = data.get("versionCli", "") | ||
| version_split = version.split(".") | ||
| if len(version_split) >= 3: | ||
| major = version_split[0] | ||
| minor = version_split[1] | ||
| patch = version_split[2] | ||
|
|
||
| version_raw = f'{major}.{minor}.{patch}' | ||
|
|
||
| version_parts = { | ||
| 'major': major, | ||
| 'minor': minor, | ||
| 'patch': patch, | ||
| } | ||
| self.set_metadata('version', version_raw, scheme='semver', part_map=version_parts) | ||
| else: | ||
| self.log.debug("Malformed N8N Server version format: %s", version) | ||
| else: | ||
| self.log.debug("Could not retrieve version metadata.") | ||
|
|
||
| def _check_n8n_health(self): | ||
| endpoint = urljoin(self.openmetrics_endpoint, self._health_endpoint) | ||
| response = self.http.get(endpoint) | ||
|
|
||
| # Any 4xx or 5xx response from the API endpoint (/healthz) means the n8n process is not responding | ||
| if 400 <= response.status_code and response.status_code < 600: | ||
| self.service_check('health.status', AgentCheck.CRITICAL, self.tags) | ||
| if response.status_code == 200: | ||
| self.service_check('health.status', AgentCheck.OK, self.tags) | ||
| else: | ||
| self.service_check('health.status', AgentCheck.UNKNOWN, self.tags) | ||
HadhemiDD marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| def _check_n8n_readiness(self): | ||
| endpoint = urljoin(self.openmetrics_endpoint, self._ready_endpoint) | ||
| response = self.http.get(endpoint) | ||
|
|
||
| # Any 4xx or 5xx response from the API endpoint (/healthz/readiness) | ||
| # means the n8n is not ready to accept requests | ||
| if 400 <= response.status_code and response.status_code < 600: | ||
| self.service_check('health.status', AgentCheck.CRITICAL, self.tags) | ||
| if response.status_code == 200: | ||
| self.service_check('health.status', AgentCheck.OK, self.tags) | ||
| else: | ||
| self.service_check('health.status', AgentCheck.UNKNOWN, self.tags) | ||
|
|
||
| def check(self, instance): | ||
| super().check(instance) | ||
| self._submit_version_metadata() | ||
| self._check_n8n_health() | ||
| self._check_n8n_readiness() | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| # (C) Datadog, Inc. 2025-present | ||
| # All rights reserved | ||
| # Licensed under a 3-clause BSD style license (see LICENSE) | ||
|
|
||
| # This file is autogenerated. | ||
| # To change this file you should edit assets/configuration/spec.yaml and then run the following commands: | ||
| # ddev -x validate config -s <INTEGRATION_NAME> | ||
| # ddev -x validate models -s <INTEGRATION_NAME> | ||
|
|
||
| from .instance import InstanceConfig | ||
| from .shared import SharedConfig | ||
|
|
||
|
|
||
| class ConfigMixin: | ||
| _config_model_instance: InstanceConfig | ||
| _config_model_shared: SharedConfig | ||
|
|
||
| @property | ||
| def config(self) -> InstanceConfig: | ||
| return self._config_model_instance | ||
|
|
||
| @property | ||
| def shared_config(self) -> SharedConfig: | ||
| return self._config_model_shared |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add a meaningful description, or remove these lines.