Skip to content
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

OpenTelemetry Implementation #1431

Closed
wants to merge 5 commits into from
Closed
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
2 changes: 2 additions & 0 deletions auto/help
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ cat << END

--njs enable njs library usage

--otel enable otel library usage

--debug enable debug logging

--fuzz=ENGINE enable fuzz testing
Expand Down
2 changes: 2 additions & 0 deletions auto/options
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ NXT_CYASSL=NO
NXT_POLARSSL=NO

NXT_NJS=NO
NXT_OTEL=NO

NXT_TEST_BUILD_EPOLL=NO
NXT_TEST_BUILD_EVENTPORT=NO
Expand Down Expand Up @@ -112,6 +113,7 @@ do
--polarssl) NXT_POLARSSL=YES ;;

--njs) NXT_NJS=YES ;;
--otel) NXT_OTEL=YES ;;

--test-build-epoll) NXT_TEST_BUILD_EPOLL=YES ;;
--test-build-eventport) NXT_TEST_BUILD_EVENTPORT=YES ;;
Expand Down
25 changes: 25 additions & 0 deletions auto/otel
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@

# Copyright (C) NGINX, Inc.


nxt_found=no
NXT_HAVE_OTEL=NO

NXT_OTEL_LIB_LOC=src/otel/target/debug/libotel.a

cat << END >> $NXT_AUTO_CONFIG_H
#ifndef NXT_HAVE_OTEL
#define NXT_HAVE_OTEL 1
#endif
END

NXT_LIB_AUX_LIBS="$NXT_LIB_AUX_LIBS $(pkgconf openssl --cflags --libs || "-lssl -lcrypto") $NXT_OTEL_LIB_LOC"

cat << END >> $NXT_MAKEFILE

$NXT_OTEL_LIB_LOC:
pushd $NXT_BUILD_DIR/src/otel/
cargo build
cd ../../

END
4 changes: 4 additions & 0 deletions auto/sources
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,10 @@ if [ "$NXT_NJS" != "NO" ]; then
NXT_LIB_SRCS="$NXT_LIB_SRCS src/nxt_js.c src/nxt_http_js.c src/nxt_script.c"
fi

if [ "$NXT_OTEL" != "NO" ]; then
NXT_LIB_SRCS="$NXT_LIB_SRCS src/nxt_otel.c"
fi

NXT_LIB_EPOLL_SRCS="src/nxt_epoll_engine.c"
NXT_LIB_KQUEUE_SRCS="src/nxt_kqueue_engine.c"
NXT_LIB_EVENTPORT_SRCS="src/nxt_eventport_engine.c"
Expand Down
1 change: 1 addition & 0 deletions auto/summary
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ Unit configuration summary:
TLS support: ............... $NXT_OPENSSL
Regex support: ............. $NXT_REGEX
njs support: ............... $NXT_NJS
otel support: .............. $NXT_OTEL

process isolation: ......... $NXT_ISOLATION
cgroupv2: .................. $NXT_HAVE_CGROUP
Expand Down
4 changes: 4 additions & 0 deletions configure
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,10 @@ if [ $NXT_NJS != NO ]; then
. auto/njs
fi

if [ $NXT_OTEL != NO ]; then
. auto/otel
fi

. auto/make
. auto/fuzzing
. auto/summary
85 changes: 85 additions & 0 deletions docs/unit-openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3090,6 +3090,68 @@ paths:
"404":
$ref: "#/components/responses/responseNotFound"

/config/settings/telemetry:
summary: "Endpoint for the `telemetry` object in `settings`"
get:
operationId: getSettingsTelemetry
summary: "Retrieve the `telemetry` object from settings"
description: "Retrieves the `telemetry` object that represents Unit's
[Telemetry settings](https://unit.nginx.org/configuration/#settings)."
tags:
- settings
- config
responses:
"200":
description: "Ok; the `telemetry` object exists in the configuration."
content:
application/json:
schema:
$ref: "#/components/schemas/configSettingsTelemetry"
"404":
$ref: "#/components/responses/responseNotFound"

put:
operationId: putSettingsTelemetry
summary: "Create or update the `telemetry` object in settings"
description: "Creates or updates the `telemetry` object that represents Unit's
[Telemetry settings](https://unit.nginx.org/configuration/#settings)."
tags:
- settings
- config
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/configSettingsTelemetry"
responses:
"200":
$ref: "#/components/responses/responseOkUpdated"

"400":
$ref: "#/components/responses/responseBadRequest"

"404":
$ref: "#/components/responses/responseNotFound"

"500":
$ref: "#/components/responses/responseInternalError"

delete:
operationId: deleteSettingsTelemetry
summary: "Delete the telemetry object"
description: "Deletes the `telemetry` object from the configuration."
tags:
- settings
- config

responses:
"200":
$ref: "#/components/responses/responseOkDeleted"

"404":
$ref: "#/components/responses/responseNotFound"

/config/settings/http:
summary: "Endpoint for the `http` object in `settings`"

Expand Down Expand Up @@ -6545,10 +6607,33 @@ components:
Unit settings."

properties:
telemetry:
description: "Represents global telemetry settings in Unit."
$ref: "#/components/schemas/configSettingsTelemetry"

http:
description: "Represents global HTTP settings in Unit."
$ref: "#/components/schemas/configSettingsHttp"

# /config/settings/telemetry
configSettingsTelemetry:
type: object
description: "An object whose options represent global telemetry settings in Unit."
required: ["endpoint"]
properties:
batch_size:
type: integer
description: "Number of spans to cache before sending to telemetry collector."
default: 128

endpoint:
type: string
description: "A valid endpoint to which Unit can send OpenTelemetry spans."

protocol:
type: string
description: "Protocol to use when communicating with the aforementioned endpoint."

# /config/settings/http
configSettingsHttp:
type: object
Expand Down
96 changes: 96 additions & 0 deletions src/nxt_conf_validation.c
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,18 @@ static nxt_int_t nxt_conf_vldt_js_module_element(nxt_conf_validation_t *vldt,
nxt_conf_value_t *value);
#endif

#if (NXT_HAVE_OTEL)
nxt_inline nxt_int_t nxt_otel_validate_endpoint(nxt_conf_validation_t *vldt,
nxt_conf_value_t *value,
void *data);
nxt_int_t nxt_otel_validate_batch_size(nxt_conf_validation_t *vldt,
nxt_conf_value_t *value,
void *data);
nxt_int_t nxt_otel_validate_protocol(nxt_conf_validation_t *vldt,
nxt_conf_value_t *value,
void *data);
#endif


static nxt_conf_vldt_object_t nxt_conf_vldt_setting_members[];
static nxt_conf_vldt_object_t nxt_conf_vldt_http_members[];
Expand Down Expand Up @@ -307,6 +319,30 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_root_members[] = {
};



#if (NXT_HAVE_OTEL)
static nxt_conf_vldt_object_t nxt_conf_vldt_otel_members[] = {
{
.name = nxt_string("endpoint"),
.type = NXT_CONF_VLDT_STRING,
.validator = nxt_otel_validate_endpoint,
.flags = NXT_CONF_VLDT_REQUIRED
}, {
.name = nxt_string("batch_size"),
.type = NXT_CONF_VLDT_INTEGER,
.validator = nxt_otel_validate_batch_size,
}, {
.name = nxt_string("protocol"),
.type = NXT_CONF_VLDT_STRING,
.validator = nxt_otel_validate_protocol,
.flags = NXT_CONF_VLDT_REQUIRED
},

NXT_CONF_VLDT_END
};
#endif


static nxt_conf_vldt_object_t nxt_conf_vldt_setting_members[] = {
{
.name = nxt_string("listen_threads"),
Expand All @@ -317,6 +353,13 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_setting_members[] = {
.type = NXT_CONF_VLDT_OBJECT,
.validator = nxt_conf_vldt_object,
.u.members = nxt_conf_vldt_http_members,
#if (NXT_HAVE_OTEL)
}, {
.name = nxt_string("telemetry"),
.type = NXT_CONF_VLDT_OBJECT,
.validator = nxt_conf_vldt_object,
.u.members = nxt_conf_vldt_otel_members,
#endif
#if (NXT_HAVE_NJS)
}, {
.name = nxt_string("js_module"),
Expand Down Expand Up @@ -1465,6 +1508,59 @@ nxt_conf_validate(nxt_conf_validation_t *vldt)
"a number, a string, an array, or an object"



#if (NXT_HAVE_OTEL)
inline nxt_int_t
nxt_otel_validate_endpoint(nxt_conf_validation_t *vldt,
nxt_conf_value_t *value,
void *data)
{
// This function is a stub for now
return NXT_OK;
}


nxt_int_t
nxt_otel_validate_batch_size(nxt_conf_validation_t *vldt,
nxt_conf_value_t *value,
void *data)
{
double batch_size;
batch_size = nxt_conf_get_number(value);
if (batch_size <= 0) {
return NXT_ERROR;
}

return NXT_OK;
}


nxt_int_t
nxt_otel_validate_protocol(nxt_conf_validation_t *vldt,
nxt_conf_value_t *value,
void *data)
{
nxt_str_t proto;

nxt_conf_get_string(value, &proto);
if (nxt_str_eq(&proto, "HTTP", 4) ||
nxt_str_eq(&proto, "http", 4)) {
goto happy;
}

if (nxt_str_eq(&proto, "GRPC", 4) ||
nxt_str_eq(&proto, "grpc", 4)) {
goto happy;
}

return NXT_ERROR;

happy:
return NXT_OK;
}
#endif


static nxt_int_t
nxt_conf_vldt_type(nxt_conf_validation_t *vldt, const nxt_str_t *name,
nxt_conf_value_t *value, nxt_conf_vldt_type_t type)
Expand Down
18 changes: 18 additions & 0 deletions src/nxt_h1proto.c
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,10 @@ static nxt_http_field_proc_t nxt_h1p_fields[] = {
{ nxt_string("Content-Length"), &nxt_http_request_content_length, 0 },
{ nxt_string("Authorization"), &nxt_http_request_field,
offsetof(nxt_http_request_t, authorization) },
#if (NXT_HAVE_OTEL)
{ nxt_string("Traceparent"), &nxt_otel_parse_traceparent, 0 },
{ nxt_string("Tracestate"), &nxt_otel_parse_tracestate, 0 },
#endif
};


Expand Down Expand Up @@ -518,6 +522,10 @@ nxt_h1p_conn_request_init(nxt_task_t *task, void *obj, void *data)
h1p->parser.discard_unsafe_fields = skcf->discard_unsafe_fields;

nxt_h1p_conn_request_header_parse(task, c, h1p);
#if (NXT_HAVE_OTEL)
hongzhidao marked this conversation as resolved.
Show resolved Hide resolved
nxt_otel_test_and_call_state(task, r);
#endif

return;
}

Expand Down Expand Up @@ -1685,6 +1693,10 @@ nxt_h1p_request_discard(nxt_task_t *task, nxt_http_request_t *r,

nxt_sendbuf_drain(task, wq, b);
nxt_sendbuf_drain(task, wq, last);

#if (NXT_HAVE_OTEL)
nxt_otel_test_and_call_state(task, r);
#endif
}


Expand Down Expand Up @@ -1824,6 +1836,12 @@ nxt_h1p_conn_sent(nxt_task_t *task, void *obj, void *data)
{
nxt_conn_t *c;
nxt_event_engine_t *engine;
#if (NXT_HAVE_OTEL)
nxt_http_request_t *r;

r = ((nxt_h1proto_t *) data)->request;
nxt_otel_test_and_call_state(task, r);
avahahn marked this conversation as resolved.
Show resolved Hide resolved
#endif
avahahn marked this conversation as resolved.
Show resolved Hide resolved

c = obj;

Expand Down
7 changes: 7 additions & 0 deletions src/nxt_http.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@

#include <nxt_regex.h>

#if (NXT_HAVE_OTEL)
#include <nxt_otel.h>
#endif

typedef enum {
NXT_HTTP_UNSET = -1,
Expand Down Expand Up @@ -190,6 +193,10 @@ struct nxt_http_request_s {

nxt_http_response_t resp;

#if (NXT_HAVE_OTEL)
nxt_otel_state_t *otel;
#endif

nxt_http_status_t status:16;

uint8_t log_route; /* 1 bit */
Expand Down
Loading