Skip to content

Commit

Permalink
Make service name in otel traces configurable
Browse files Browse the repository at this point in the history
  • Loading branch information
bonnefoa committed Aug 5, 2024
1 parent 181ec39 commit 3b4153a
Show file tree
Hide file tree
Showing 8 changed files with 62 additions and 13 deletions.
4 changes: 4 additions & 0 deletions doc/pg_tracing.md
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,10 @@ URL of the otel collector to send spans to. Example: 'http://127.0.0.1:4318/v1/t

Interval in milliseconds between upload of spans to the otel collector. This parameter can only be set at server start.

### pg_tracing.otel_service_name (string)

Service name to set in traces sent to otel collector. This parameter can only be set at server start.

### pg_tracing.otel_connect_timeout_ms (integer)

Maximum time in milliseconds to connect to the otel collector. This includes DNS resolution and protocol handshake. This parameter can only be set at server start.
18 changes: 18 additions & 0 deletions expected/json.out
Original file line number Diff line number Diff line change
Expand Up @@ -106,5 +106,23 @@ SELECT trace_id, name, parameters, deparse_info, lvl FROM peek_ordered_json_span
00000000000000000000000000000001 | IndexScan using pg_tracing_index on pg_tracing_test | | Index Cond: (a = 1) | 3
(4 rows)

CALL clean_spans();
-- Test service name
/*traceparent='00-00000000000000000000000000000001-0000000000000001-01'*/ SELECT * FROM pg_tracing_test WHERE a=1;
a | b
---+----------------------
1 | aaa
(1 row)

SELECT trace_id, name, service_name FROM peek_ordered_json_spans;
trace_id | name | service_name
----------------------------------+-----------------------------------------------------+---------------------
00000000000000000000000000000001 | SELECT * FROM pg_tracing_test WHERE a=$1; | "PostgreSQL_Server"
00000000000000000000000000000001 | Planner | "PostgreSQL_Server"
00000000000000000000000000000001 | ExecutorRun | "PostgreSQL_Server"
00000000000000000000000000000001 | IndexScan using pg_tracing_index on pg_tracing_test | "PostgreSQL_Server"
(4 rows)

-- Cleanup
CALL reset_settings();
CALL clean_spans();
9 changes: 6 additions & 3 deletions expected/utility.out
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@ CREATE VIEW peek_ordered_spans AS
-- Column type to convert json to record
create type span_json as ("traceId" text, "parentSpanId" text, "spanId" text, name text, "startTimeUnixNano" text, "endTimeUnixNano" text, attributes jsonb, kind int, status jsonb);
CREATE VIEW peek_json_spans AS
SELECT * FROM jsonb_populate_recordset(null::span_json, (SELECT jsonb_path_query_array(pg_tracing_json_spans()::jsonb, '$.resourceSpans[0].scopeSpans[*].spans[*]')));
SELECT *, jsonb_path_query_first(pg_tracing_json_spans()::jsonb, '$.resourceSpans[0].resource.attributes[0].value.stringValue') as service_name
FROM jsonb_populate_recordset(null::span_json, (SELECT jsonb_path_query_array(pg_tracing_json_spans()::jsonb, '$.resourceSpans[0].scopeSpans[*].spans[*]')));
CREATE FUNCTION get_int_attribute(attributes jsonb, keyvalue text) returns bigint
LANGUAGE SQL
IMMUTABLE
Expand All @@ -97,10 +98,10 @@ CREATE FUNCTION get_string_array_attribute(attributes jsonb, keyvalue text) retu
'$ ? (@.key == $key)', jsonb_build_object('key', keyvalue)),
'$.value.arrayValue.values[*].stringValue[*]'))), '{}'));
-- View spans generated from json with their nested level
-- TODO: There's probably a way to make this cleaner...
-- TODO: There's probably a better way to do this...
CREATE VIEW peek_json_spans_with_level AS
WITH RECURSIVE list_trace_spans(trace_id, parent_id, span_id, name, span_start, span_end,
kind, query_id, pid, userid, dbid, sql_error_code, subxact_count,
kind, service_name, query_id, pid, userid, dbid, sql_error_code, subxact_count,
status_code, status_message,
plan_startup_cost, plan_total_cost, plan_rows, plan_width,
rows, nloops,
Expand All @@ -113,6 +114,7 @@ WITH RECURSIVE list_trace_spans(trace_id, parent_id, span_id, name, span_start,
startup, parameters, deparse_info,
lvl) AS (
SELECT p."traceId", p."parentSpanId", p."spanId", p."name", p."startTimeUnixNano", p."endTimeUnixNano", p.kind,
p.service_name,
get_int_attribute(p.attributes, 'query.query_id'),
get_int_attribute(p.attributes, 'backend.pid'),
get_int_attribute(p.attributes, 'backend.user_id'),
Expand Down Expand Up @@ -155,6 +157,7 @@ WITH RECURSIVE list_trace_spans(trace_id, parent_id, span_id, name, span_start,
FROM peek_json_spans p where not "parentSpanId"=ANY(SELECT span_id from pg_tracing_peek_spans)
UNION ALL
SELECT s."traceId", s."parentSpanId", s."spanId", s."name", s."startTimeUnixNano", s."endTimeUnixNano", s.kind,
s.service_name,
get_int_attribute(s.attributes, 'query.query_id'),
get_int_attribute(s.attributes, 'backend.pid'),
get_int_attribute(s.attributes, 'backend.user_id'),
Expand Down
6 changes: 6 additions & 0 deletions sql/json.sql
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ CALL clean_spans();
-- Test parameters and deparse_info
/*dddbs='postgres.db',traceparent='00-00000000000000000000000000000001-0000000000000001-01'*/ SELECT * FROM pg_tracing_test WHERE a=1;
SELECT trace_id, name, parameters, deparse_info, lvl FROM peek_ordered_json_spans;
CALL clean_spans();

-- Test service name
/*traceparent='00-00000000000000000000000000000001-0000000000000001-01'*/ SELECT * FROM pg_tracing_test WHERE a=1;
SELECT trace_id, name, service_name FROM peek_ordered_json_spans;

-- Cleanup
CALL reset_settings();
CALL clean_spans();
9 changes: 6 additions & 3 deletions sql/utility.sql
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,8 @@ CREATE VIEW peek_ordered_spans AS
-- Column type to convert json to record
create type span_json as ("traceId" text, "parentSpanId" text, "spanId" text, name text, "startTimeUnixNano" text, "endTimeUnixNano" text, attributes jsonb, kind int, status jsonb);
CREATE VIEW peek_json_spans AS
SELECT * FROM jsonb_populate_recordset(null::span_json, (SELECT jsonb_path_query_array(pg_tracing_json_spans()::jsonb, '$.resourceSpans[0].scopeSpans[*].spans[*]')));
SELECT *, jsonb_path_query_first(pg_tracing_json_spans()::jsonb, '$.resourceSpans[0].resource.attributes[0].value.stringValue') as service_name
FROM jsonb_populate_recordset(null::span_json, (SELECT jsonb_path_query_array(pg_tracing_json_spans()::jsonb, '$.resourceSpans[0].scopeSpans[*].spans[*]')));

CREATE FUNCTION get_int_attribute(attributes jsonb, keyvalue text) returns bigint
LANGUAGE SQL
Expand Down Expand Up @@ -112,10 +113,10 @@ CREATE FUNCTION get_string_array_attribute(attributes jsonb, keyvalue text) retu
'$.value.arrayValue.values[*].stringValue[*]'))), '{}'));

-- View spans generated from json with their nested level
-- TODO: There's probably a way to make this cleaner...
-- TODO: There's probably a better way to do this...
CREATE VIEW peek_json_spans_with_level AS
WITH RECURSIVE list_trace_spans(trace_id, parent_id, span_id, name, span_start, span_end,
kind, query_id, pid, userid, dbid, sql_error_code, subxact_count,
kind, service_name, query_id, pid, userid, dbid, sql_error_code, subxact_count,
status_code, status_message,
plan_startup_cost, plan_total_cost, plan_rows, plan_width,
rows, nloops,
Expand All @@ -128,6 +129,7 @@ WITH RECURSIVE list_trace_spans(trace_id, parent_id, span_id, name, span_start,
startup, parameters, deparse_info,
lvl) AS (
SELECT p."traceId", p."parentSpanId", p."spanId", p."name", p."startTimeUnixNano", p."endTimeUnixNano", p.kind,
p.service_name,
get_int_attribute(p.attributes, 'query.query_id'),
get_int_attribute(p.attributes, 'backend.pid'),
get_int_attribute(p.attributes, 'backend.user_id'),
Expand Down Expand Up @@ -170,6 +172,7 @@ WITH RECURSIVE list_trace_spans(trace_id, parent_id, span_id, name, span_start,
FROM peek_json_spans p where not "parentSpanId"=ANY(SELECT span_id from pg_tracing_peek_spans)
UNION ALL
SELECT s."traceId", s."parentSpanId", s."spanId", s."name", s."startTimeUnixNano", s."endTimeUnixNano", s.kind,
s.service_name,
get_int_attribute(s.attributes, 'query.query_id'),
get_int_attribute(s.attributes, 'backend.pid'),
get_int_attribute(s.attributes, 'backend.user_id'),
Expand Down
13 changes: 13 additions & 0 deletions src/pg_tracing.c
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,8 @@ static char *pg_tracing_filter_query_ids = NULL; /* only sample query
* matching query ids */
static char *pg_tracing_otel_endpoint = NULL; /* Otel collector to send
* spans to */
char *pg_tracing_otel_service_name = NULL; /* Service name set in
* otel traces */
static int pg_tracing_otel_naptime; /* Delay between upload of spans to
* otel collector */
static int pg_tracing_otel_connect_timeout_ms; /* Connect timeout to the otel
Expand Down Expand Up @@ -487,6 +489,17 @@ _PG_init(void)
NULL,
NULL);

DefineCustomStringVariable("pg_tracing.otel_service_name",
"Service Name to set in traces sent to otel.",
NULL,
&pg_tracing_otel_service_name,
"PostgreSQL_Server",
PGC_POSTMASTER,
0,
NULL,
NULL,
NULL);

DefineCustomStringVariable("pg_tracing.trace_context",
"Trace context propagated through GUC variable.",
NULL,
Expand Down
2 changes: 2 additions & 0 deletions src/pg_tracing.h
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,7 @@ typedef struct JsonContext
int span_type_count[NUM_SPAN_TYPE];
const Span **span_type_to_spans[NUM_SPAN_TYPE];
const char *spans_str;
const char *service_name;
} JsonContext;

typedef struct SpanContext
Expand Down Expand Up @@ -421,6 +422,7 @@ extern pgTracingSharedState * pg_tracing_shared_state;
extern pgTracingSpans * shared_spans;
extern char *shared_str;
extern int nested_level;
extern char *pg_tracing_otel_service_name;

extern void
store_span(const Span * span);
Expand Down
14 changes: 7 additions & 7 deletions src/pg_tracing_json.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,13 +132,12 @@ append_attribute_double(StringInfo str, const char *key, double value, bool skip
}

static void
append_resource(StringInfo str)
append_resource(JsonContext * json_ctx)
{
appendStringInfo(str, "\"resource\":");
appendStringInfo(str, "{\"attributes\": [");
/* TODO: Make the service name configurable */
append_attribute_string(str, "service.name", "PostgreSQL_Server", false);
appendStringInfo(str, "]}");
appendStringInfo(json_ctx->str, "\"resource\":");
appendStringInfo(json_ctx->str, "{\"attributes\": [");
append_attribute_string(json_ctx->str, "service.name", json_ctx->service_name, false);
appendStringInfo(json_ctx->str, "]}");
}

static void
Expand Down Expand Up @@ -410,6 +409,7 @@ build_json_context(JsonContext * json_ctx, const pgTracingSpans * pgTracingSpans
memset(json_ctx->span_type_to_spans, 0, sizeof(json_ctx->span_type_to_spans));
json_ctx->spans_str = spans_str;
json_ctx->num_spans = num_spans;
json_ctx->service_name = pg_tracing_otel_service_name;

aggregate_span_by_type(json_ctx, pgTracingSpans);
}
Expand All @@ -421,7 +421,7 @@ void
marshal_spans_to_json(JsonContext * json_ctx)
{
appendStringInfo(json_ctx->str, "{\"resourceSpans\": [{");
append_resource(json_ctx->str);
append_resource(json_ctx);
appendStringInfoChar(json_ctx->str, ',');
append_scope_spans_array(json_ctx);
appendStringInfo(json_ctx->str, "}]}");
Expand Down

0 comments on commit 3b4153a

Please sign in to comment.