Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Makefile.conf.template
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#mi_xmlrpc_ng= New version of the xmlrpc server that handles xmlrpc requests and generates xmlrpc responses. | parsing/building XML library, typically libxml
#mmgeoip= Lightweight wrapper for the MaxMind GeoIP API | libGeoIP
#osp= Enables OpenSIPS to support secure, multi-lateral peering using the OSP standard | OSP development kit, typically osptoolkit
#opentelemetry= OpenTelemetry tracing for OpenSIPS routes | OpenTelemetry C++ SDK (opentelemetry-cpp)
#perl= Easily implement your own OpenSIPS extensions in Perl | Perl library development files, typically libperl-dev
#pi_http= Provides a simple web database provisioning interface | XML parsing & building library, typically libxml-dev
#rabbitmq_consumer= Receive AMQP messages which will be delivered by triggering events | RabbitMQ development library, librabbitmq-dev
Expand Down Expand Up @@ -75,7 +76,7 @@
#uuid= UUID generator | uuid-dev

# the below definition must be one single line (no wrapping) to make the "menuconfig" tool happy
exclude_modules?= aaa_diameter aaa_radius auth_jwt auth_web3 b2b_logic_xml cachedb_cassandra cachedb_couchbase cachedb_dynamodb cachedb_memcached cachedb_mongodb cachedb_redis carrierroute cgrates compression cpl_c db_berkeley db_http db_mysql db_oracle db_perlvdb db_postgres db_sqlite db_unixodbc dialplan emergency event_rabbitmq event_kafka event_sqs h350 httpd http2d identity jabber json launch_darkly ldap lua mi_xmlrpc_ng mmgeoip osp perl pi_http presence presence_dialoginfo presence_mwi presence_reginfo presence_xml presence_dfks proto_ipsec proto_sctp proto_tls proto_wss pua pua_bla pua_dialoginfo pua_mi pua_reginfo pua_usrloc pua_xmpp python regex rabbitmq_consumer rest_client rls rtp.io siprec sngtc snmpstats stir_shaken tls_mgm tls_openssl tls_wolfssl uuid xcap xcap_client xml xmpp
exclude_modules?= aaa_diameter aaa_radius auth_jwt auth_web3 b2b_logic_xml cachedb_cassandra cachedb_couchbase cachedb_dynamodb cachedb_memcached cachedb_mongodb cachedb_redis carrierroute cgrates compression cpl_c db_berkeley db_http db_mysql db_oracle db_perlvdb db_postgres db_sqlite db_unixodbc dialplan emergency event_rabbitmq event_kafka event_sqs h350 httpd http2d identity jabber json launch_darkly ldap lua mi_xmlrpc_ng mmgeoip opentelemetry osp perl pi_http presence presence_dialoginfo presence_mwi presence_reginfo presence_xml presence_dfks proto_ipsec proto_sctp proto_tls proto_wss pua pua_bla pua_dialoginfo pua_mi pua_reginfo pua_usrloc pua_xmpp python regex rabbitmq_consumer rest_client rls rtp.io siprec sngtc snmpstats stir_shaken tls_mgm tls_openssl tls_wolfssl uuid xcap xcap_client xml xmpp

include_modules?=

Expand Down
37 changes: 37 additions & 0 deletions action.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
#include "script_var.h"
#include "xlog.h"
#include "cfg_pp.h"
#include "route_trace.h"

#include <string.h>

Expand Down Expand Up @@ -215,6 +216,8 @@ int run_top_route(struct script_route sr, struct sip_msg* msg)
int bk_action_flags, route_stack_start_bkp = -1, route_stack_size_bkp;
int ret;
context_p ctx = NULL;
const char *trace_file = NULL;
int trace_line = 0;

bk_action_flags = action_flags;

Expand Down Expand Up @@ -251,9 +254,27 @@ int run_top_route(struct script_route sr, struct sip_msg* msg)
else
route_stack[route_stack_start] = sr.name;

if (route_trace_enabled()) {
if (sr.a && sr.a->file) {
trace_file = sr.a->file;
trace_line = sr.a->line;
}
route_trace_msg_start(msg, route_type, route_stack[route_stack_start],
route_stack_size, route_stack_start);
route_trace_route_enter(msg, route_type, route_stack[route_stack_start],
trace_file, trace_line, route_stack_size, route_stack_start);
}

run_actions(sr.a, msg);
ret = action_flags;

if (route_trace_enabled()) {
route_trace_route_exit(msg, route_type, route_stack[route_stack_start],
NULL, 0, route_stack_size, route_stack_start, ret);
route_trace_msg_end(msg, route_type, route_stack[route_stack_start],
route_stack_size, route_stack_start, ret);
}

if (route_stack_start_bkp != -1) {
route_stack_size = route_stack_size_bkp;
route_stack_start = route_stack_start_bkp;
Expand Down Expand Up @@ -808,12 +829,28 @@ int do_action(struct action* a, struct sip_msg* msg)
}
route_params_push_level(sroutes->request[i].name,
route_p, (void *)(unsigned long)len, route_param_get);
if (route_trace_enabled())
route_trace_route_enter(msg, route_type,
sroutes->request[i].name, a->file, a->line,
route_stack_size, route_stack_start);
return_code=run_actions(sroutes->request[i].a, msg);
if (route_trace_enabled())
route_trace_route_exit(msg, route_type,
sroutes->request[i].name, a->file, a->line,
route_stack_size, route_stack_start, return_code);
route_params_release(route_p, len);
route_params_pop_level();
} else {
route_params_push_level(sroutes->request[i].name, NULL, 0, route_param_get);
if (route_trace_enabled())
route_trace_route_enter(msg, route_type,
sroutes->request[i].name, a->file, a->line,
route_stack_size, route_stack_start);
return_code=run_actions(sroutes->request[i].a, msg);
if (route_trace_enabled())
route_trace_route_exit(msg, route_type,
sroutes->request[i].name, a->file, a->line,
route_stack_size, route_stack_start, return_code);
route_params_pop_level();
}
ret=return_code;
Expand Down
3 changes: 2 additions & 1 deletion dprint.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,11 +105,12 @@
#undef NO_LOG
#endif

#define MAX_LOG_CONS_NO 3
#define MAX_LOG_CONS_NO 4

#define STDERR_CONSUMER_NAME "stderror"
#define SYSLOG_CONSUMER_NAME "syslog"
#define EVENT_CONSUMER_NAME "event"
#define OTEL_CONSUMER_NAME "opentelemetry"

#define LOG_PLAIN_NAME "plain_text"
#define LOG_JSON_NAME "json"
Expand Down
27 changes: 27 additions & 0 deletions modules/opentelemetry/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# WARNING: do not run this directly, it should be run by the master Makefile

include ../../Makefile.defs

NAME=opentelemetry.so

CXX?=g++

# Make sure the C++ object participates in linking and overrides any defaults
# from the shared Makefile logic (which only considers .c sources).
override extra_objs+=opentelemetry.o

# Always use the system-installed OpenTelemetry C++ SDK (via pkg-config).
OTEL_CPP_CFLAGS:=$(shell pkg-config --cflags opentelemetry_trace opentelemetry_resources opentelemetry_common opentelemetry_api)
OTEL_CPP_LIBS:=$(shell pkg-config --libs opentelemetry_trace opentelemetry_resources opentelemetry_logs opentelemetry_metrics opentelemetry_common) -lopentelemetry_exporter_otlp_http
ifeq ($(strip $(OTEL_CPP_CFLAGS)$(OTEL_CPP_LIBS)),)
$(error OpenTelemetry C++ SDK not found via pkg-config (opentelemetry_*). Please install the system libraries.)
endif

DEFS+=-DHAVE_OPENTELEMETRY_CPP
CXXFLAGS+=-std=c++17 -fpermissive $(OTEL_CPP_CFLAGS)
LIBS+=$(OTEL_CPP_LIBS)

include ../../Makefile.modules

opentelemetry.o: opentelemetry.cpp
$(Q)$(CXX) $(CXXFLAGS) $(DEFS) $(INCLUDE) -fPIC -c $< -o $@
27 changes: 27 additions & 0 deletions modules/opentelemetry/doc/opentelemetry.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding='UTF-8'?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd" [

<!ENTITY admin SYSTEM "opentelemetry_admin.xml">
<!ENTITY contrib SYSTEM "contributors.xml">

<!-- Include general documentation entities -->
<!ENTITY % docentities SYSTEM "../../../doc/entities.xml">
%docentities;

]>

<book>
<bookinfo>
<title>opentelemetry Module</title>
<productname class="trade">&osipsname;</productname>
</bookinfo>
<toc></toc>

&admin;
&contrib;

&docCopyrights;
<para>&copyright; 2026 &osipsproj;</para>

</book>
203 changes: 203 additions & 0 deletions modules/opentelemetry/doc/opentelemetry_admin.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
<!-- Module User's Guide -->

<chapter>

<title>&adminguide;</title>

<section id="overview" xreflabel="Overview">
<title>Overview</title>
<para>
The <emphasis>opentelemetry</emphasis> module provides OpenTelemetry
tracing for &osips; route execution. It creates a root span per
processed SIP message and a child span for each route entry.
</para>
<para>
Spans include common SIP attributes (method, Call-ID, CSeq, status) and
message metadata. While a span is active, &osips; logs can be attached
as OpenTelemetry events for easier correlation.
</para>
<para>
Trace data is exported via the OTLP/HTTP exporter from the
OpenTelemetry C++ SDK.
</para>
</section>

<section id="dependencies" xreflabel="Dependencies">
<title>Dependencies</title>
<section>
<title>&osips; Modules</title>
<para>
The following modules must be loaded before this module:
<itemizedlist>
<listitem>
<para>
<emphasis>None</emphasis>.
</para>
</listitem>
</itemizedlist>
</para>
</section>

<section>
<title>External Libraries or Applications</title>
<para>
The following libraries or applications must be installed before
running &osips; with this module loaded:
<itemizedlist>
<listitem>
<para>
<emphasis>OpenTelemetry C++ SDK</emphasis> (opentelemetry-cpp),
with the OTLP/HTTP exporter enabled.
</para>
</listitem>
</itemizedlist>
</para>
</section>
</section>

<section id="exported_parameters" xreflabel="Exported Parameters">
<title>Exported Parameters</title>

<section id="param_enable" xreflabel="enable">
<title><varname>enable</varname> (integer)</title>
<para>
Enables or disables OpenTelemetry tracing at startup. It can also be
changed at runtime using the <function moreinfo="none">otel_enable</function>
MI command.
</para>
<para>
If &osips; was built without the OpenTelemetry C++ SDK, enabling this
parameter will fail at startup.
</para>
<para>
<emphasis>
Default value is <quote>0 (disabled)</quote>.
</emphasis>
</para>
<example>
<title>Set <varname>enable</varname> parameter</title>
<programlisting format="linespecific">
...
modparam("opentelemetry", "enable", 1)
...
</programlisting>
</example>
</section>

<section id="param_log_level" xreflabel="log_level">
<title><varname>log_level</varname> (integer)</title>
<para>
Log level threshold used by the OpenTelemetry log consumer when
attaching log events to the active span.
</para>
<para>
<emphasis>
Default value is <quote>L_DBG</quote>.
</emphasis>
</para>
<example>
<title>Set <varname>log_level</varname> parameter</title>
<programlisting format="linespecific">
...
modparam("opentelemetry", "log_level", 3)
...
</programlisting>
</example>
</section>

<section id="param_use_batch" xreflabel="use_batch">
<title><varname>use_batch</varname> (integer)</title>
<para>
Selects the OpenTelemetry span processor. When enabled, the module uses
the batch span processor; otherwise it uses the simple span processor.
</para>
<para>
<emphasis>
Default value is <quote>1 (enabled)</quote>.
</emphasis>
</para>
<example>
<title>Set <varname>use_batch</varname> parameter</title>
<programlisting format="linespecific">
...
modparam("opentelemetry", "use_batch", 0)
...
</programlisting>
</example>
</section>

<section id="param_service_name" xreflabel="service_name">
<title><varname>service_name</varname> (string)</title>
<para>
Sets the OpenTelemetry <quote>service.name</quote> resource attribute.
</para>
<para>
<emphasis>
Default value is <quote>opensips</quote>.
</emphasis>
</para>
<example>
<title>Set <varname>service_name</varname> parameter</title>
<programlisting format="linespecific">
...
modparam("opentelemetry", "service_name", "edge-proxy")
...
</programlisting>
</example>
</section>

<section id="param_exporter_endpoint" xreflabel="exporter_endpoint">
<title><varname>exporter_endpoint</varname> (string)</title>
<para>
Overrides the OTLP/HTTP exporter endpoint. If empty, the OpenTelemetry
SDK default is used.
</para>
<para>
<emphasis>
Default value is <quote>empty</quote>.
</emphasis>
</para>
<example>
<title>Set <varname>exporter_endpoint</varname> parameter</title>
<programlisting format="linespecific">
...
modparam("opentelemetry", "exporter_endpoint", "http://127.0.0.1:4318/v1/traces")
...
</programlisting>
</example>
</section>
</section>

<section id="exported_mi_functions" xreflabel="Exported MI Functions">
<title>Exported MI Functions</title>

<section id="mi_otel_enable" xreflabel="otel_enable">
<title>
<function moreinfo="none">otel_enable</function>
</title>
<para>
Enables or disables OpenTelemetry tracing at runtime.
</para>
<para>
Name: <emphasis>otel_enable</emphasis>
</para>
<para>Parameters:</para>
<itemizedlist>
<listitem><para>
<emphasis>enable</emphasis> - set to <quote>1</quote> to enable
tracing or <quote>0</quote> to disable it.
</para></listitem>
</itemizedlist>
<para>
MI FIFO Command Format:
</para>
<programlisting format="linespecific">
## enable tracing
opensips-cli -x mi otel_enable enable=1
## disable tracing
opensips-cli -x mi otel_enable enable=0
</programlisting>
</section>
</section>

</chapter>
Loading
Loading