Skip to content

Commit

Permalink
Adding semantic-convention attributes for trace (#868)
Browse files Browse the repository at this point in the history
  • Loading branch information
lalitb authored Jul 30, 2021
1 parent ef16d00 commit 5414ebe
Show file tree
Hide file tree
Showing 7 changed files with 227 additions and 166 deletions.
189 changes: 189 additions & 0 deletions api/include/opentelemetry/trace/semantic_conventions.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

#pragma once

#include "opentelemetry/common/string_util.h"
#include "opentelemetry/version.h"

OPENTELEMETRY_BEGIN_NAMESPACE
namespace trace
{

#define OTEL_CPP_GET_ATTR(name) attr(OTEL_CPP_CONST_HASHCODE(name))

/**
* Stores the Constants for semantic kAttribute names outlined by the OpenTelemetry specifications.
* <see
* href="https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/README.md"/>.
*/
static const struct
{
uint32_t attribute_id;
const char *attribute_key;
} attribute_ids[] = {
// The set of constants matches the specification as of this commit.
// https://github.com/open-telemetry/opentelemetry-specification/tree/main/specification/trace/semantic_conventions
// https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/exceptions.md

// General network connection attributes
{OTEL_CPP_CONST_HASHCODE(AttrNetTransport), "net.transport"},
{OTEL_CPP_CONST_HASHCODE(AttrNetPeerIp), "net.peer.ip"},
{OTEL_CPP_CONST_HASHCODE(AttrNetPeerPort), "net.peer.port"},
{OTEL_CPP_CONST_HASHCODE(AttrNetPeerName), "net.peer.name"},
{OTEL_CPP_CONST_HASHCODE(AttrNetHostIp), "net.host.ip"},
{OTEL_CPP_CONST_HASHCODE(AttrNetHostPort), "net.host.port"},
{OTEL_CPP_CONST_HASHCODE(AttrNetHostName), "net.host.name"},

// General identity attributes
{OTEL_CPP_CONST_HASHCODE(AttrEnduserId), "enduser.id"},
{OTEL_CPP_CONST_HASHCODE(AttrEnduserRole), "enduser.role"},
{OTEL_CPP_CONST_HASHCODE(AttrEnduserScope), "enduser.scope"},

// General remote service attributes
{OTEL_CPP_CONST_HASHCODE(AttrPeerService), "peer.service"},

// General thread attributes
{OTEL_CPP_CONST_HASHCODE(AttrThreadId), "thread.id"},
{OTEL_CPP_CONST_HASHCODE(AttrThreadName), "thread.name"},

// Source Code Attributes
{OTEL_CPP_CONST_HASHCODE(AttrCodeFunction), "code.function"},
{OTEL_CPP_CONST_HASHCODE(AttrCodeNamespace), "code.namespace"},
{OTEL_CPP_CONST_HASHCODE(AttrCodeFilepath), "code.filepath"},
{OTEL_CPP_CONST_HASHCODE(AttrCodeLineno), "code.lineno"},

// Http Span Common Attributes
{OTEL_CPP_CONST_HASHCODE(AttrHttpMethod), "http.method"},
{OTEL_CPP_CONST_HASHCODE(AttrHttpUrl), "http.url"},
{OTEL_CPP_CONST_HASHCODE(AttrHttpTarget), "http.target"},
{OTEL_CPP_CONST_HASHCODE(AttrHttpHost), "http.host"},
{OTEL_CPP_CONST_HASHCODE(AttrHttpScheme), "http.scheme"},
{OTEL_CPP_CONST_HASHCODE(AttrHttpStatusCode), "http.status_code"},
{OTEL_CPP_CONST_HASHCODE(AttrHttpFlavor), "http.flavor"},
{OTEL_CPP_CONST_HASHCODE(AttrHttpUserAgent), "http.user_agent"},
{OTEL_CPP_CONST_HASHCODE(AttrHttpRequestContentLength), "http.request_content_length"},
{OTEL_CPP_CONST_HASHCODE(AttrHttpRequestContentLengthUncompressed),
"http.request_content_length_uncompressed"},
{OTEL_CPP_CONST_HASHCODE(AttrHttpResponseContentLength), "http.response_content_length"},
{OTEL_CPP_CONST_HASHCODE(AttrHttpResponseContentLengthUncompressed),
"http.response_content_length_uncompressed"},

// HTTP Span Client Attributes
// One of the following combinations:
// - http.url
// - http.scheme, http.host, http.target
// - http.scheme, net.peer.name, net.peer.port, http.target
// - http.scheme, net.peer.ip, net.peer.port, http.target

// HTTP Span Server Attributes
// One of the following combinations:
// -http.scheme, http.host, http.target
// -http.scheme, http.server_name, net.host.port, http.target
// -http.scheme, net.host.name, net.host.port, http.target
// -http.url
{OTEL_CPP_CONST_HASHCODE(AttrHttpServerName), "http.server_name"},
{OTEL_CPP_CONST_HASHCODE(AttrHttpRoute), "http.route"},
{OTEL_CPP_CONST_HASHCODE(AttrHttpClientIp), "http.client_ip"},

// DB: Connection-level attributes
{OTEL_CPP_CONST_HASHCODE(AttrDbSystem), "db.system"}, // other_sql, mssql, mysql...
{OTEL_CPP_CONST_HASHCODE(AttrDbConnectionString), "db.connection_string"},
{OTEL_CPP_CONST_HASHCODE(AttrDbUser), "db.user"},
// DB: Connection-level attributes for specific technologies
{OTEL_CPP_CONST_HASHCODE(AttrDbMssqlInstanceName), "db.mssql.instance_name"},
{OTEL_CPP_CONST_HASHCODE(AttrDbJdbcDriverClassname), "db.jdbc.driver_classname"},
// DB: Call-level attributes
{OTEL_CPP_CONST_HASHCODE(AttrDbName), "db.name"},
{OTEL_CPP_CONST_HASHCODE(AttrDbStatement), "db.statement"},
{OTEL_CPP_CONST_HASHCODE(AttrDbOperation), "db.operation"},
// DB: Call-level attributes for specific technologies
{OTEL_CPP_CONST_HASHCODE(AttrDbHbaseNamespace), "db.hbase.namespace"},
{OTEL_CPP_CONST_HASHCODE(AttrDbRedisDatabaseIndex), "db.redis.database_index"},
{OTEL_CPP_CONST_HASHCODE(AttrDbMongodbCollection), "db.mongodb.collection"},

// // DB: Call-level attributes for Cassandra for clarity
{OTEL_CPP_CONST_HASHCODE(AttrDbCassandraKeyspace), "db.cassandra.keyspace"},
{OTEL_CPP_CONST_HASHCODE(AttrDbCassandraPageSize), "db.cassandra.page_size"},
{OTEL_CPP_CONST_HASHCODE(AttrDbCassandraConsistencyLevel), "db.cassandra.consistency_level"},
{OTEL_CPP_CONST_HASHCODE(AttrDbCassandraTable), "db.cassandra.table"},
{OTEL_CPP_CONST_HASHCODE(AttrDbCassandraIdempotence), "db.cassandra.idempotence"},
{OTEL_CPP_CONST_HASHCODE(AttrDbCassandraSpeculativeExecutionCount),
"db.cassandra.speculative_execution_count"},
{OTEL_CPP_CONST_HASHCODE(AttrDbCassandraCoordinatorId), "db.cassandra.coordinator.id"},
{OTEL_CPP_CONST_HASHCODE(AttrDbCassandraCoordinatorDC), "db.cassandra.coordinator.dc"},

// Common RPC attributes
{OTEL_CPP_CONST_HASHCODE(AttrRpcSystem), "rpc.system"},
{OTEL_CPP_CONST_HASHCODE(AttrRpcService), "rpc.service"},
{OTEL_CPP_CONST_HASHCODE(AttrRpcMethod), "rpc.method"},
// gRPC attributes
{OTEL_CPP_CONST_HASHCODE(AttrRpcGrpcStatusCode), "rpc.grpc.status_code"},
// JSON-RPC attributes
{OTEL_CPP_CONST_HASHCODE(AttrRpcJsonrpcVersion), "rpc.jsonrpc.version"},
{OTEL_CPP_CONST_HASHCODE(AttrRpcJsonrpcRequestId), "rpc.jsonrpc.request_id"},
{OTEL_CPP_CONST_HASHCODE(AttrRpcJsonrpcErrorCode), "rpc.jsonrpc.error_code"},
{OTEL_CPP_CONST_HASHCODE(AttrRpcJsonrpcErrorMessage), "rpc.jsonrpc.error_message"},

// faas: General Attributes
{OTEL_CPP_CONST_HASHCODE(AttrFaasTrigger), "faas.trigger"},
{OTEL_CPP_CONST_HASHCODE(AttrFaasExecution), "faas.execution"},
// faas: incoming invocations
{OTEL_CPP_CONST_HASHCODE(AttrFaasColdStart), "faas.coldstart"},
// faas: outgoing invocations
{OTEL_CPP_CONST_HASHCODE(AttrFaasInvokedName), "faas.invoked_name"},
{OTEL_CPP_CONST_HASHCODE(AttrFaasInvokedProvider), "faas.invoked_provider"},
{OTEL_CPP_CONST_HASHCODE(AttrFaasInvokedRegion), "faas.invoked_region"},
// faas: datastore trigger
{OTEL_CPP_CONST_HASHCODE(AttrFaasDocumentCollection), "faas.document.collection"},
{OTEL_CPP_CONST_HASHCODE(AttrFaasDocumentOperation), "faas.document.operation"},
{OTEL_CPP_CONST_HASHCODE(AttrFaasDocumentTime), "faas.document.time"},
{OTEL_CPP_CONST_HASHCODE(AttrFaasDocumentName), "faas.document.name"},
// faas: timer trigger
{OTEL_CPP_CONST_HASHCODE(AttrFaasTime), "faas.time"},
{OTEL_CPP_CONST_HASHCODE(AttrFaasCron), "faas.cron"},

// messaging attributes
{OTEL_CPP_CONST_HASHCODE(AttrMessagingSystem), "messaging.system"},
{OTEL_CPP_CONST_HASHCODE(AttrMessagingDestination), "messaging.destination"},
{OTEL_CPP_CONST_HASHCODE(AttrMessagingDestinationKind), "messaging.destination_kind"},
{OTEL_CPP_CONST_HASHCODE(AttrMessagingTempDestination), "messaging.temp_destination"},
{OTEL_CPP_CONST_HASHCODE(AttrMessagingProtocol), "messaging.protocol"},
{OTEL_CPP_CONST_HASHCODE(AttrMessagingProtocolVersion), "messaging.protocol_version"},
{OTEL_CPP_CONST_HASHCODE(AttrMessagingUrl), "messaging.url"},
{OTEL_CPP_CONST_HASHCODE(AttrMessagingMessageId), "messaging.message_id"},
{OTEL_CPP_CONST_HASHCODE(AttrMessagingConversationId), "messaging.conversation_id"},
{OTEL_CPP_CONST_HASHCODE(AttrMessagingPayloadSize), "messaging.message_payload_size_bytes"},
{OTEL_CPP_CONST_HASHCODE(AttrMessagingPayloadCompressedSize),
"messaging.message_payload_compressed_size_bytes"},
{OTEL_CPP_CONST_HASHCODE(AttrMessagingOperation), "messaging.operation"},
// messaging attributes specific to messaging systems
{OTEL_CPP_CONST_HASHCODE(AttrMessagingRabbitMQRoutingKey), "messaging.rabbitmq.routing_key"},
{OTEL_CPP_CONST_HASHCODE(AttrMessagingKafkaMessageKey), "messaging.kafka.message_key"},
{OTEL_CPP_CONST_HASHCODE(AttrMessagingKafkaConsumerGroup), "messaging.kafka.consumer_group"},
{OTEL_CPP_CONST_HASHCODE(AttrMessagingKafkaClientId), "messaging.kafka.client_id"},
{OTEL_CPP_CONST_HASHCODE(AttrMessagingKafkaPartition), "messaging.kafka.partition"},
{OTEL_CPP_CONST_HASHCODE(AttrMessagingKafkaTombstone), "messaging.kafka.tombstone"},

// Exceptions attributes
{OTEL_CPP_CONST_HASHCODE(AttrExceptionType), "exception.type"},
{OTEL_CPP_CONST_HASHCODE(AttrExceptionMessage), "exception.message"},
{OTEL_CPP_CONST_HASHCODE(AttrExceptionStacktrace), "exception.stacktrace"},
{OTEL_CPP_CONST_HASHCODE(AttrExceptionEscapted), "exception.escaped"},
};
// function to generate hash code for semantic conventions attributes.

#define OTEL_CPP_TRACE_ATTRIBUTES_MAX (sizeof(attribute_ids) / sizeof(attribute_ids[0]))

inline const char *attr(uint32_t attr)
{
for (int i = 0; i < OTEL_CPP_TRACE_ATTRIBUTES_MAX; i++)
{
if (attribute_ids[i].attribute_id == attr)
return attribute_ids[i].attribute_key;
}
return "";
}

} // namespace trace
OPENTELEMETRY_END_NAMESPACE
16 changes: 9 additions & 7 deletions examples/grpc/client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "messages.grpc.pb.h"
#endif

#include "opentelemetry/trace/semantic_conventions.h"
#include "tracer_common.h"
#include <iostream>
#include <memory>
Expand All @@ -26,6 +27,7 @@ using grpc_example::GreetResponse;
namespace
{

using namespace opentelemetry::trace;
class GreeterClient
{
public:
Expand All @@ -44,11 +46,11 @@ class GreeterClient

std::string span_name = "GreeterClient/Greet";
auto span = get_tracer("grpc")->StartSpan(span_name,
{{"rpc.system", "grpc"},
{"rpc.service", "grpc-example.GreetService"},
{"rpc.method", "Greet"},
{"net.peer.ip", ip},
{"net.peer.port", port}},
{{OTEL_CPP_GET_ATTR(AttrRpcSystem), "grpc"},
{OTEL_CPP_GET_ATTR(AttrRpcService), "grpc-example.GreetService"},
{OTEL_CPP_GET_ATTR(AttrRpcMethod), "Greet"},
{OTEL_CPP_GET_ATTR(AttrNetPeerIp), ip},
{OTEL_CPP_GET_ATTR(AttrNetPeerPort), port}},
options);

auto scope = get_tracer("grpc-client")->WithActiveSpan(span);
Expand All @@ -64,7 +66,7 @@ class GreeterClient
if (status.ok())
{
span->SetStatus(opentelemetry::trace::StatusCode::kOk);
span->SetAttribute("rpc.grpc.status_code", status.error_code());
span->SetAttribute(OTEL_CPP_GET_ATTR(AttrRpcGrpcStatusCode), status.error_code());
// Make sure to end your spans!
span->End();
return response.response();
Expand All @@ -73,7 +75,7 @@ class GreeterClient
{
std::cout << status.error_code() << ": " << status.error_message() << std::endl;
span->SetStatus(opentelemetry::trace::StatusCode::kError);
span->SetAttribute("rpc.grpc.status_code", status.error_code());
span->SetAttribute(OTEL_CPP_GET_ATTR(AttrRpcGrpcStatusCode), status.error_code());
// Make sure to end your spans!
span->End();
return "RPC failed";
Expand Down
10 changes: 6 additions & 4 deletions examples/grpc/server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#endif
#include "tracer_common.h"
#include "opentelemetry/trace/span_context_kv_iterable_view.h"
#include "opentelemetry/trace/semantic_conventions.h"

#include <grpcpp/grpcpp.h>
#include <grpcpp/server.h>
Expand All @@ -30,6 +31,7 @@ using grpc_example::GreetResponse;

using Span = opentelemetry::trace::Span;
using SpanContext = opentelemetry::trace::SpanContext;
using namespace opentelemetry::trace;

namespace
{
Expand Down Expand Up @@ -59,10 +61,10 @@ class GreeterServer final : public Greeter::Service
std::string span_name = "GreeterService/Greet";
auto span = get_tracer("grpc")
->StartSpan(span_name,
{{"rpc.system", "grpc"},
{"rpc.service", "GreeterService"},
{"rpc.method", "Greet"},
{"rpc.grpc.status_code", 0}},
{{OTEL_CPP_GET_ATTR(AttrRpcSystem), "grpc"},
{OTEL_CPP_GET_ATTR(AttrRpcService), "GreeterService"},
{OTEL_CPP_GET_ATTR(AttrRpcMethod), "Greet"},
{OTEL_CPP_GET_ATTR(AttrRpcGrpcStatusCode), 0}},
options);
auto scope = get_tracer("grpc")->WithActiveSpan(span);

Expand Down
11 changes: 7 additions & 4 deletions examples/http/client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@

#include "opentelemetry/ext/http/client/http_client_factory.h"
#include "opentelemetry/ext/http/common/url_parser.h"
#include "opentelemetry/trace/semantic_conventions.h"
#include "tracer_common.h"

namespace
{

using namespace opentelemetry::trace;

void sendRequest(const std::string &url)
{
auto http_client = opentelemetry::ext::http::client::HttpClientFactory::CreateSync();
Expand All @@ -20,9 +23,9 @@ void sendRequest(const std::string &url)
std::string span_name = url_parser.path_;
auto span = get_tracer("http-client")
->StartSpan(span_name,
{{"http.url", url_parser.url_},
{"http.scheme", url_parser.scheme_},
{"http.method", "GET"}},
{{OTEL_CPP_GET_ATTR(AttrHttpUrl), url_parser.url_},
{OTEL_CPP_GET_ATTR(AttrHttpScheme), url_parser.scheme_},
{OTEL_CPP_GET_ATTR(AttrHttpMethod), "GET"}},
options);
auto scope = get_tracer("http-client")->WithActiveSpan(span);

Expand All @@ -38,7 +41,7 @@ void sendRequest(const std::string &url)
{
// set span attributes
auto status_code = result.GetResponse().GetStatusCode();
span->SetAttribute("http.status_code", status_code);
span->SetAttribute(OTEL_CPP_GET_ATTR(AttrHttpStatusCode), status_code);
result.GetResponse().ForEachHeader([&span](opentelemetry::nostd::string_view header_name,
opentelemetry::nostd::string_view header_value) {
span->SetAttribute("http.header." + std::string(header_name.data()), header_value);
Expand Down
25 changes: 14 additions & 11 deletions examples/http/server.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,17 @@
// SPDX-License-Identifier: Apache-2.0

#include "server.h"
#include "opentelemetry/trace/semantic_conventions.h"
#include "tracer_common.h"

#include <iostream>
#include <thread>

namespace
{

using namespace opentelemetry::trace;
;
uint16_t server_port = 8800;
constexpr const char *server_name = "localhost";

Expand All @@ -31,17 +35,16 @@ class RequestHandler : public HTTP_SERVER_NS::HttpRequestCallback
options.parent = opentelemetry::trace::propagation::GetSpan(new_context)->GetContext();

// start span with parent context extracted from http header
auto span =
get_tracer("http-server")
->StartSpan(
span_name,
{{"http.server_name", server_name},
{"net.host.port", server_port},
{"http.method", request.method},
{"http.scheme", "http"},
{"http.request_content_length", static_cast<uint64_t>(request.content.length())},
{"http.client_ip", request.client}},
options);
auto span = get_tracer("http-server")
->StartSpan(span_name,
{{OTEL_CPP_GET_ATTR(AttrHttpServerName), server_name},
{OTEL_CPP_GET_ATTR(AttrNetHostPort), server_port},
{OTEL_CPP_GET_ATTR(AttrHttpMethod), request.method},
{OTEL_CPP_GET_ATTR(AttrHttpScheme), "http"},
{OTEL_CPP_GET_ATTR(AttrHttpRequestContentLength),
static_cast<uint64_t>(request.content.length())},
{OTEL_CPP_GET_ATTR(AttrHttpClientIp), request.client}},
options);

auto scope = get_tracer("http_server")->WithActiveSpan(span);

Expand Down
6 changes: 2 additions & 4 deletions sdk/include/opentelemetry/sdk/resource/semantic_conventions.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
#pragma once

#include <stdint.h>
#include <iostream>
#include <type_traits>
#include <unordered_map>

Expand All @@ -20,7 +18,7 @@ static const std::unordered_map<uint32_t, const char *> attribute_ids = {
{OTEL_CPP_CONST_HASHCODE(AttrServiceName), "service.name"},
{OTEL_CPP_CONST_HASHCODE(AttrServiceNamespace), "service.namespace"},
{OTEL_CPP_CONST_HASHCODE(AttrServiceInstance), "service.instance.id"},
{OTEL_CPP_CONST_HASHCODE(AttrServiceVersion), "service.version "},
{OTEL_CPP_CONST_HASHCODE(AttrServiceVersion), "service.version"},

// telemetry attributes
{OTEL_CPP_CONST_HASHCODE(AttrTelemetrySdkName), "telemetry.sdk.name"},
Expand Down Expand Up @@ -123,7 +121,7 @@ static const std::unordered_map<uint32_t, const char *> attribute_ids = {
{OTEL_CPP_CONST_HASHCODE(AttrCronjobUid), "k8s.cronjob.id"},
{OTEL_CPP_CONST_HASHCODE(AttrCronjobName), "k8s.cronjob.name"}};

// macro and function to generate hash code for semantic conventions attributes.
// function to generate hash code for semantic conventions attributes.
inline const char *attr(uint32_t attr)
{
return (attribute_ids.find(attr) != attribute_ids.end()) ? attribute_ids.at(attr) : "";
Expand Down
Loading

0 comments on commit 5414ebe

Please sign in to comment.