You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[OpenTelemetry](https://opentelemetry.io/) is an open-source framework for collecting, generating, and exporting telemetry data like traces, metrics, and logs, from applications to help monitor and troubleshoot them. In this article we show you how to capture traces from your OpenFaaS functions.
16
+
[OpenTelemetry](https://opentelemetry.io/) is an open-source observability framework. This article shows you how to use OpenTelemetry to capture traces from OpenFaaS functions.
17
17
18
-

18
+

19
+
> Function trace of the order function accessing a PostgreSQL database and invoking the order-confirmation function. The function is auto-instrumented, exporting traces for both database queries and HTTP requests without requiring any code changes or manual span definitions.
19
20
20
-
OpenFaaS functions can be instrumented manually by either explicitly adding code to the function to capture telemetry data or, for supported languages, by leveraging [auto-instrumentation](https://opentelemetry.io/docs/zero-code/). Auto-instrumentation uses built in tools or agents to automatically collect telemetry without changing your function code.
21
+
OpenFaaS functions can be instrumented manually using OpenTelemetry by either explicitly adding code to the function to capture telemetry data or, for supported languages, by leveraging [auto-instrumentation](https://opentelemetry.io/docs/zero-code/). Auto-instrumentation uses built in tools or agents to automatically collect telemetry without changing your function code.
21
22
22
23
While OpenTelemetry aims to be a comprehensive solution that covers traces, logs and metrics we are going to focus exclusively on traces in this article. Traces can be a great addition to the wide [range of Prometheus metrics](https://docs.openfaas.com/architecture/metrics/) OpenFaaS already makes available for monitoring functions.
23
24
24
25
**What value does tracing bring to functions?**
25
26
26
-
By collecting traces from functions, especially in more complex applications where functions are chained together or where they are calling a lot of external services traces can help you:
27
+
By collecting traces from functions, especially in more complex applications where functions are chained together or where they are calling a lot of external services, traces can help you:
27
28
28
-
- Identify performance bottlenecks
29
+
- Identify performance bottlenecks.
29
30
- Detect errors and perform root cause analysis.
30
31
- Understand system behaviour.
31
32
32
-
However tracing comes with some trade-offs as well. It requires additional infrastructure, incurs extra costs and adds cognitive overhead for instrumenting functions and managing telemetry data.
33
+
However tracing comes with some trade-offs as well. It requires additional infrastructure, such as cloud storage or compute resources, which may increase costs, and adds cognitive overhead from instrumenting functions and managing telemetry data.
34
+
35
+
33
36
34
37

35
38
> Diagram showing the different components involved in collecting traces from functions.
36
39
37
40
## What we'll cover
38
41
39
-
This tutorial shows you how to use OpenTelemetry to capture traces from OpenFaaS functions, helping you debug issues and optimize performance. We'll use zero-code instrumentation to keep things simple, setting up a tracing pipeline with open-source tools. Here's what we'll cover:
42
+
This tutorial shows you how to use OpenTelemetry to capture traces from OpenFaaS functions, helping you debug issues and optimize performance. We'll use auto-instrumentation to keep things simple, setting up a tracing pipeline with open-source tools. Here's what we'll cover:
40
43
41
44
- Deploy [Grafana Tempo](https://grafana.com/oss/tempo/) as the backend for storing traces.
42
45
- Run and configure [Grafana Alloy](https://grafana.com/oss/alloy-opentelemetry-collector/) as a [Collector](https://opentelemetry.io/docs/collector/) for traces.
@@ -195,7 +198,7 @@ The `alloy.configMap.content` section contains the content of the Alloy configur
195
198
196
199
Checkout the docs for more details on [how to configure Grafana Alloy to collect OpenTelemetry data](https://grafana.com/docs/alloy/latest/collect/opentelemetry-data/)
197
200
198
-
The OTLP receiver needs the be reachable by functions so they can send their telemetry data. The `extraPorts` parameter is used to add both HTTP and gRPC ports to the alloy service that is created by the Chart.
201
+
The OTLP receiver needs to be reachable by functions so they can send their telemetry data. The `extraPorts` parameter is used to add both HTTP and gRPC ports to the alloy service that is created by the Chart.
199
202
200
203
To deploy Alloy to the cluster run:
201
204
@@ -222,11 +225,11 @@ kubectl get pods --namespace monitoring
222
225
223
226
OpenTelemetry zero code instrumentation allows you to collect telemetry data from your OpenFaaS functions without making any changes to your functions code.
224
227
225
-
Instead of manually adding OpenTelemetry SDK calls to your codebase, zero-code instrumentation relies on agents to inject the necessary instrumentation at runtime.
228
+
Instead of manually adding OpenTelemetry SDK calls to your codebase, auto-instrumentation relies on agents to inject the necessary instrumentation at runtime.
226
229
227
-
At the time of writing OpenTelemetry has zero-code instrumentation support for [JavaScript](https://opentelemetry.io/docs/zero-code/js/), [Python](https://opentelemetry.io/docs/zero-code/python/), [PHP](https://opentelemetry.io/docs/zero-code/php/), [Java]() and [.NET](https://opentelemetry.io/docs/zero-code/dotnet/) with [Go](https://opentelemetry.io/docs/zero-code/go/) support being a work in progress.
230
+
At the time of writing OpenTelemetry has auto-instrumentation support for [JavaScript](https://opentelemetry.io/docs/zero-code/js/), [Python](https://opentelemetry.io/docs/zero-code/python/), [PHP](https://opentelemetry.io/docs/zero-code/php/), [Java](https://opentelemetry.io/docs/zero-code/java/) and [.NET](https://opentelemetry.io/docs/zero-code/dotnet/) with [Go](https://opentelemetry.io/docs/zero-code/go/) support being a work in progress.
228
231
229
-
For most languages using zero-code instrumentation for OpenFaaS functions will require you to [customise the language template](https://docs.openfaas.com/cli/templates/#how-to-customise-a-template). There are two ways to customise a template:
232
+
For most languages using auto-instrumentation for OpenFaaS functions will require you to [customise the language template](https://docs.openfaas.com/cli/templates/#how-to-customise-a-template). There are two ways to customise a template:
230
233
231
234
- Fork the template repository and modify the template. Recommended method that allows for distribution and reuse of the template.
232
235
- Pull the template and apply patches directly in the `./template/<language_name>` directory. Good for quick iteration and experimentation with template modifications. The modified template can not be shared and reused. Changes may get overwritten when pulling templates again.
@@ -284,7 +287,7 @@ We are making use of [environment variable substitution](https://docs.openfaas.c
284
287
285
288
The `NODE_OPTIONS` environment variable needs to have the value `--require @opentelemetry/auto-instrumentations-node/register` to register and initialize the auto instrumentation module.
286
289
287
-
The `OTEL_EXPORTER_OTLP_ENDPOINT` env variable is used to specify the endpoint of the OTLP receiver to which telemetry data should be sent. The url of the Alloy instance we deployed in the cluster is used as the default value.
290
+
The `OTEL_EXPORTER_OTLP_ENDPOINT` env variable is used to specify the endpoint of the OTLP receiver to which telemetry data should be sent. The URL of the Alloy instance we deployed in the cluster is used as the default value.
288
291
289
292
For this tutorial we are only interested in traces, by setting `OTEL_METRICS_EXPORTER` and `OTEL_LOGS_EXPORTER` to `none` we disable the metrics and logs exporters.
290
293
@@ -295,13 +298,13 @@ Checkout the [configuration docs](https://opentelemetry.io/docs/zero-code/js/con
295
298
296
299
**Deploy the function**
297
300
298
-
Test the function locally with `faass-cli local-run` and the `console` exporter. This should output the exporter outputs to stdout/console, a good way to quickly check the instrumentation configuration.
301
+
Test the function locally with `faas-cli local-run` and the `console` exporter. This should output the exporter outputs to stdout/console, a good way to quickly check the instrumentation configuration.
299
302
300
303
```sh
301
304
EXPORTER="console" faas-cli local-run echo
302
305
```
303
306
304
-
Invoke the function to function to verify traces get exported to the console:
307
+
Invoke the function to verify traces get exported to the console:
The `opentelemetry-bootstrap -a install` command reads through the list of packages installed in your active site-packages folder, and installs the corresponding instrumentation libraries for these packages, if applicable. The OpenTelemetry Python agent uses [monkey patching](https://stackoverflow.com/questions/5626193/what-is-monkey-patching) to modify functions in these libraries at runtime.
346
349
347
-
Update the fprocess ENV in the Dockerfile to start the OpenTelemetry agent:
350
+
Update the function process in `./template/python3-http/template.yaml`to run `"opentelemetry-instrument`.
We use [environment variable substitution](https://docs.openfaas.com/reference/yaml/#yaml-environment-variable-substitution) in the stack file to make parameters easily configurable when deploying the function.
383
384
384
-
`OTEL_SERVICE_NAME`sets the name of the service associated with the telemetry and is used to identify telemetry for a specific function. It can be set to any value you want be we recommend using the clear function identifier `<fn-name>.<fn-namespace>`.
385
+
`OTEL_SERVICE_NAME`sets the name of the service associated with the telemetry and is used to identify telemetry for a specific function. It can be set to any value you want, but we recommend using the clear function identifier `<fn-name>.<fn-namespace>`.
385
386
386
-
The `OTEL_EXPORTER_OTLP_ENDPOINT` env variable is used to specify the endpoint of the OTLP receiver to which telemetry data should be sent. The url of the Alloy instance we deployed in the cluster is used as the default value.
387
+
The `OTEL_EXPORTER_OTLP_ENDPOINT` env variable is used to specify the endpoint of the OTLP receiver to which telemetry data should be sent. The URL of the Alloy instance we deployed in the cluster is used as the default value.
387
388
388
389
For this tutorial we are only interested in traces, by setting `OTEL_METRICS_EXPORTER` and `OTEL_LOGS_EXPORTER` to `none` we disable the metrics and logs exporters.
389
390
390
-
By default the Agent will instrument any [supported package](https://opentelemetry.io/ecosystem/registry/?language=python&component=instrumentation) it can. You can omit specific packages from instrumentation by using the `OTEL_PYTHON_DISABLED_INSTRUMENTATIONS environment` variable.
391
+
By default the Agent will instrument any [supported package](https://opentelemetry.io/ecosystem/registry/?language=python&component=instrumentation) it can. You can omit specific packages from instrumentation by using the `OTEL_PYTHON_DISABLED_INSTRUMENTATIONS` environment variable.
391
392
392
393
Checkout the [configuration docs](https://opentelemetry.io/docs/zero-code/python/configuration/) for more details and to see all available configuration options.
393
394
@@ -442,7 +443,7 @@ You can now use the Explore tab to start exploring traces. Make sure to select T
442
443
443
444
Checkout the Grafana documentation for more info on how to [add traces visualizations to a Grafana dashboard](https://grafana.com/docs/grafana/latest/panels-visualizations/visualizations/traces/#traces)
444
445
445
-
## Expand an auto-instrumented function with manual traces
446
+
## Add manual traces to your function
446
447
447
448
Auto instrumentation captures traces from the standard library and known libraries at the edges of the function, such as inbound and outbound HTTP requests. To capture traces for custom business logic or spans for things that go on inside the function you will have to add some manual instrumentation.
Collecting telemetry is also supported on [OpenFaaS Edge](https://docs.openfaas.com/edge/overview/). The Alloy collector can be deployed as an additional service. Detailed instructions on how to configure Alloy and add it to the `docker-compose.yaml` file are available in [our documentation](https://docs.openfaas.com/edge/open-telemetry/).
529
+
Collecting telemetry is also supported on [OpenFaaS Edge](https://docs.openfaas.com/edge/overview/). OpenFaaS Edge is a lightweight option for running OpenFaaS functions that does not use Kubernetes, ideal for edge computing environments.
530
+
531
+
When using OpenFaaS Edge the Alloy collector can be deployed as an additional service and configured to export traces to an external backend. Detailed instructions on how to configure Alloy and add it to the `docker-compose.yaml` file are available in [our documentation](https://docs.openfaas.com/edge/open-telemetry/).
529
532
530
533
Any instrumented function can be deployed to OpenFaaS Edge. Just make sure the `OTEL_EXPORTER_OTLP_ENDPOINT` environment variable is set correctly.
531
534
Modify the `stack.yaml` file and change the environment variable to `alloy:4317`. Or use the environment substitution to override it. In OpenFaaS Edge the service name can be used as the hostname.
@@ -537,21 +540,21 @@ OTEL_EXPORTER_OTLP_ENDPOINT=alloy:4317 faas-cli up
537
540
538
541
## Conclusion
539
542
540
-
In this tutorial we showed how OpenTelemetry zero-code instrumentation can be used to quickly get telemetry and traces for OpenFaaS functions without having to manually instrument your functions code.
543
+
In this tutorial we showed how OpenTelemetry auto-instrumentation can be used to quickly get telemetry and traces for OpenFaaS functions without having to manually instrument your functions code.
541
544
542
545
We ran through the process of deploying and configuring a [Collector](https://opentelemetry.io/docs/collector/), and tracing backend to collect and store traces for OpenFaaS functions. While we used [Grafana Alloy](https://grafana.com/oss/alloy-opentelemetry-collector/) as the Collector and [Grafana Tempo](https://grafana.com/oss/tempo/) to store traces these components can be exchanged easily without changing instrumentation for functions.
543
546
544
-
Other common open-source alternatives for collecting and storing traces include: [Jeager and Zipkin](https://edgedelta.com/company/blog/the-battle-of-tracers-jaeger-vs-zipkin-the-complete-comparison)
547
+
Other common open-source alternatives for collecting and storing traces include: [Jaeger and Zipkin](https://edgedelta.com/company/blog/the-battle-of-tracers-jaeger-vs-zipkin-the-complete-comparison)
545
548
546
-
I you are a Datadog user take a look at [how to collect OpenTelemetry data in datadog](https://docs.datadoghq.com/opentelemetry/). For more alternatives see: [vendors who natively support OpenTelemetry](https://opentelemetry.io/ecosystem/vendors/)
549
+
If you are a Datadog user take a look at [how to collect OpenTelemetry data in datadog](https://docs.datadoghq.com/opentelemetry/). For more alternatives see: [vendors who natively support OpenTelemetry](https://opentelemetry.io/ecosystem/vendors/)
547
550
548
551
To support auto instrumentation some minor customisations to the OpenFaaS function templates are required. We walked through the steps to modify the Node.js and Python templates. With python we took it one step further and extended the auto instrumented traces with some custom spans.
549
552
550
553
### Auto-instrumentation with OpenTelemetry Operator for Kubernetes
551
554
552
-
If you are using OpenFaaS on Kubernetes there is the option to use the [OpenTelemetry Operator for Kubernetes ](https://opentelemetry.io/docs/platforms/kubernetes/operator/) to [inject zero-code instrumentation](https://opentelemetry.io/docs/platforms/kubernetes/operator/automatic/). The Operator supports injecting and configuring auto-instrumentation libraries for .NET, Java, Node.js, Python and Go functions. It requires no changes to your existing functions, however it comes with a couple of tradeoffs.
555
+
If you are using OpenFaaS on Kubernetes there is the option to use the [OpenTelemetry Operator for Kubernetes ](https://opentelemetry.io/docs/platforms/kubernetes/operator/) for [auto-instrumentation](https://opentelemetry.io/docs/platforms/kubernetes/operator/automatic/). The Operator supports injecting and configuring auto-instrumentation libraries for .NET, Java, Node.js, Python and Go functions. It requires no changes to your existing functions, however it comes with a couple of tradeoffs.
553
556
554
-
- Depending on the language, the instrumentation relies on init-containers, mounting volumes or using sidecars. This can increase the [cold-start](https://docs.openfaas.com/architecture/autoscaling/#scaling-up-from-zero-replicas) when autoscaling functions.
557
+
- Depending on the language, the instrumentation relies on init-containers, mounting volumes or using sidecars. This can increase the [cold-start](https://docs.openfaas.com/architecture/autoscaling/#scaling-up-from-zero-replicas) when autoscaling functions as it causing an extra delay when the container initializes.
555
558
- Go instrumentation works through a sidecar container that uses eBPF and requires elevated permissions for the function.
556
559
557
560
We recommend using function templates and the `stack.yaml` configuration described in this article instead. It does not have these tradeoffs and ensures your functions are portable to other OpenFaaS versions that do not use Kubernetes, like [OpenFaaS Edge](https://docs.openfaas.com/deployment/edge/).
0 commit comments