Skip to content

Commit 6842162

Browse files
weltekialexellis
authored andcommitted
Fix caption and various suggestions
Signed-off-by: Han Verstraete (OpenFaaS Ltd) <han@openfaas.com>
1 parent ffaa90d commit 6842162

File tree

1 file changed

+33
-30
lines changed

1 file changed

+33
-30
lines changed

_posts/2025-05-12-trace-functions-with-opentelemetry.md

Lines changed: 33 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -13,30 +13,33 @@ image: "/images/2025-05-opentelemetry/background.png"
1313
hide_header_image: true
1414
---
1515

16-
[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.
1717

18-
![Screenshot of a trace visualization in Grafana](/images/2025-05-opentelemetry/db-access-trace-detail.png)
18+
![Screenshot of a trace visualization for the order function in Grafana](/images/2025-05-opentelemetry/db-access-trace-detail.png)
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.
1920
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.
2122

2223
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.
2324

2425
**What value does tracing bring to functions?**
2526

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:
2728

28-
- Identify performance bottlenecks
29+
- Identify performance bottlenecks.
2930
- Detect errors and perform root cause analysis.
3031
- Understand system behaviour.
3132

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+
3336

3437
![Diagram showing the different components involved in collecting traces from functions.](/images/2025-05-opentelemetry/function-otel-collection-diagram.png)
3538
> Diagram showing the different components involved in collecting traces from functions.
3639
3740
## What we'll cover
3841

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:
4043

4144
- Deploy [Grafana Tempo](https://grafana.com/oss/tempo/) as the backend for storing traces.
4245
- 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
195198

196199
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/)
197200

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.
199202

200203
To deploy Alloy to the cluster run:
201204

@@ -222,11 +225,11 @@ kubectl get pods --namespace monitoring
222225

223226
OpenTelemetry zero code instrumentation allows you to collect telemetry data from your OpenFaaS functions without making any changes to your functions code.
224227

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.
226229

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.
228231

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:
230233

231234
- Fork the template repository and modify the template. Recommended method that allows for distribution and reuse of the template.
232235
- 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
284287

285288
The `NODE_OPTIONS` environment variable needs to have the value `--require @opentelemetry/auto-instrumentations-node/register` to register and initialize the auto instrumentation module.
286289

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.
288291

289292
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.
290293

@@ -295,13 +298,13 @@ Checkout the [configuration docs](https://opentelemetry.io/docs/zero-code/js/con
295298

296299
**Deploy the function**
297300

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.
299302

300303
```sh
301304
EXPORTER="console" faas-cli local-run echo
302305
```
303306

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:
305308

306309
```sh
307310
curl -i http://127.0.0.1:8080 -d "Hello OTEL"
@@ -344,14 +347,12 @@ RUN pip install --no-cache-dir --user -r requirements.txt
344347

345348
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.
346349

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`.
348351

349352
```diff
350-
# configure WSGI server and healthcheck
351-
USER app
352-
353-
- ENV fprocess="python index.py"
354-
+ ENV fprocess="opentelemetry-instrument python index.py"
353+
language: python3-http
354+
- fprocess: python index.py
355+
+ fprocess: opentelemetry-instrument python index.py
355356
```
356357

357358
**Create a new function**
@@ -381,13 +382,13 @@ functions:
381382

382383
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.
383384

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>`.
385386

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.
387388

388389
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.
389390

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.
391392

392393
Checkout the [configuration docs](https://opentelemetry.io/docs/zero-code/python/configuration/) for more details and to see all available configuration options.
393394

@@ -442,7 +443,7 @@ You can now use the Explore tab to start exploring traces. Make sure to select T
442443

443444
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)
444445

445-
## Expand an auto-instrumented function with manual traces
446+
## Add manual traces to your function
446447

447448
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.
448449

@@ -525,7 +526,9 @@ curl -i "http://127.0.0.1:8080/function/order?id=1"
525526

526527
## OpenTelemetry on OpenFaaS Edge
527528

528-
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/).
529532

530533
Any instrumented function can be deployed to OpenFaaS Edge. Just make sure the `OTEL_EXPORTER_OTLP_ENDPOINT` environment variable is set correctly.
531534
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
537540

538541
## Conclusion
539542

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.
541544

542545
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.
543546

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)
545548

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/)
547550

548551
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.
549552

550553
### Auto-instrumentation with OpenTelemetry Operator for Kubernetes
551554

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.
553556

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.
555558
- Go instrumentation works through a sidecar container that uses eBPF and requires elevated permissions for the function.
556559

557560
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

Comments
 (0)