* ``DISABLE_OPENSSL_ERROR_STRINGS`` to disable the loading of OpenSSL's error strings, reducing the memory use at the cost of human-readable error messages
* ``DISABLE_NPN`` for Next Protocol Negotiation, superseded by ALPN
* ``DISABLE_PROMETHEUS`` for prometheus
-* ``DISABLE_PROTOBUF`` for protocol-buffer support, including dnstap
+* ``DISABLE_PROTOBUF`` for protocol-buffer support, including dnstap and Open Telemetry Tracing
* ``DISABLE_RECVMMSG`` for ``recvmmsg`` support
* ``DISABLE_RULES_ALTERING_QUERIES`` to remove rules altering the content of queries
* ``DISABLE_SECPOLL`` for security polling
:returns: A table of tags, using strings as keys and values
+ .. method:: DNSQuestion:getTraceID() -> string
+
+ .. versionadded:: 2.1.0
+
+ When :doc:`OpenTelemetry tracing <ottrace>` is enabled for this query, get the ID of the trace. Otherwise, ``nil``. The value is an opaque binary string.
+
+ :returns: A binary string containing the OpenTelemetry trace identifier
+
.. method:: DNSQuestion:getTrailingData() -> string
.. versionadded:: 1.4.0
--- /dev/null
+OpenTelemetry Tracing
+---------------------
+
+.. warning::
+ Tracing support is considered experimental. The output, configuration, and any other details
+ may change at any time.
+
+Since version 2.1.0, when :program:`dnsdist` is built with ProtoBuf support, sent messages (using e.g. :func:`RemoteLogResponseAction`) can contain `OpenTelemetry traces <https://opentelemetry.io/docs/concepts/signals/traces>`__ data.
+
+Per-query tracing can be enabled using the :func:`SetTraceAction` or :func:`SetTraceResponseAction`. However :program:`dnsdist` captures some data before rules processing in order to have tracing information from before the rules are evaluated.
+When tracing is enabled in the query, :program:`dnsdist` stores start and end times of certain (but not all) functions that are called during the lifetime of the query and the response.
+It is recommended to send the traces out through a RemoteLogger in ResponseRules, to capture as much information as possible.
+
+.. note::
+ At the moment, the ProtoBuf message is sent out **during** the processing of the response rules.
+ Hence, the traces are not complete.
+ There are plans to remedy this, but no timeline to do so.
+
+Tracing uses more memory and CPU than usual query processing and it is recommended to enable tracing only for certain queries using specific :doc:`selectors <selectors>`.
+
+Example configuration
+=====================
+
+.. code-block:: yaml
+
+ remote_logging:
+ protobuf_loggers:
+ - name: pblog
+ address: 127.0.0.1:5301
+ query_rules:
+ - name: Enable tracing
+ selector:
+ # Just as an example, in production don't trace all the queries
+ type: All
+ action:
+ type: SetTrace
+ value: true
+ response_rules:
+ - name: Do PB logging
+ selector:
+ type: All
+ action:
+ type: RemoteLog
+ logger_name: pblog
+
+Passing Trace ID to downstream servers
+======================================
+
+When storing traces, it is beneficial to correlate traces of the same query through different applications.
+The `PowerDNS Recursor <https://doc.powerdns.com/recursor>`__ (since 5.3.0) supports the experimental `draft-edns-otel-trace-ids <https://github.com/PowerDNS/draft-edns-otel-trace-ids>`__ EDNS option to pass the trace identifier.
+The :doc:`DNSQuestion object <dq>` supports the :func:`getTraceID <DNSQuestion:getTraceID>` method to retrieve the trace identifier as a binary string.
+Combining all this, a :func:`LuaAction` can be used to add this EDNS option to the query.
+
+.. code-block:: yaml
+
+ - name: Add TraceID to EDNS for backend
+ selector:
+ type: All
+ action:
+ type: Lua
+ function_code: |
+ return function (dq)
+ tid = dq:getTraceID()
+ if (tid ~= nil) then
+ -- PowerDNS Recursor uses EDNS Option Code 65500.
+ dq:setEDNSOption(65500, "\000\000" .. tid)
+ end
+ return DNSAction.None
+ end