Skip to content

Commit

Permalink
Automatically generate semantic conventions from the spec (open-telem…
Browse files Browse the repository at this point in the history
  • Loading branch information
marcalff committed Jul 14, 2022
1 parent 801ebba commit 15cf768
Show file tree
Hide file tree
Showing 16 changed files with 2,027 additions and 68 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
// https://github.com/open-telemetry/opentelemetry-specification/tree/v1.0.0/specification/trace/semantic_conventions
// and MAY will change in future.

#warning "This file is deprecated. Use opentelemetry/trace/semantic_conventions.h"

#pragma once

#include "opentelemetry/common/string_util.h"
Expand Down
1,140 changes: 1,140 additions & 0 deletions api/include/opentelemetry/trace/semantic_conventions.h

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions buildscripts/semantic-convention/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
opentelemetry-specification/
55 changes: 55 additions & 0 deletions buildscripts/semantic-convention/generate.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#!/bin/bash

#
# Adapted from:
# opentelemetry-java/buildscripts/semantic-convention/generate.sh
# for opentelemetry-cpp
#

SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
ROOT_DIR="${SCRIPT_DIR}/../../"

# freeze the spec & generator tools versions to make SemanticAttributes generation reproducible
SEMCONV_VERSION=1.9.0
SPEC_VERSION=v$SEMCONV_VERSION
SCHEMA_URL=https://opentelemetry.io/schemas/$SEMCONV_VERSION
GENERATOR_VERSION=0.7.0

cd ${SCRIPT_DIR}

rm -rf opentelemetry-specification || true
mkdir opentelemetry-specification
cd opentelemetry-specification

git init
git remote add origin https://github.com/open-telemetry/opentelemetry-specification.git
git fetch origin "$SPEC_VERSION"
git reset --hard FETCH_HEAD
cd ${SCRIPT_DIR}

docker run --rm \
-v ${SCRIPT_DIR}/opentelemetry-specification/semantic_conventions/trace:/source \
-v ${SCRIPT_DIR}/templates:/templates \
-v ${ROOT_DIR}/api/include/opentelemetry/trace/:/output \
otel/semconvgen:$GENERATOR_VERSION \
-f /source code \
--template /templates/SemanticAttributes.h.j2 \
--output /output/semantic_conventions.h \
-Dclass=SemanticConventions \
-DschemaUrl=$SCHEMA_URL \
-Dnamespace_open="namespace trace {" \
-Dnamespace_close="}"

docker run --rm \
-v ${SCRIPT_DIR}/opentelemetry-specification/semantic_conventions/resource:/source \
-v ${SCRIPT_DIR}/templates:/templates \
-v ${ROOT_DIR}/sdk/include/opentelemetry/sdk/resource/:/output \
otel/semconvgen:$GENERATOR_VERSION \
-f /source code \
--template /templates/SemanticAttributes.h.j2 \
--output /output/semantic_conventions.h \
-Dclass=SemanticConventions \
-DschemaUrl=$SCHEMA_URL \
-Dnamespace_open="namespace sdk { namespace resource {" \
-Dnamespace_close="} }"

109 changes: 109 additions & 0 deletions buildscripts/semantic-convention/templates/SemanticAttributes.h.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
{#
Adapted from:
opentelemetry-java/buildscripts/semantic-convention/templates/SemanticAttributes.java.j2
for opentelemetry-cpp
#}
{%- macro to_cpp_return_type(type) -%}
{%- if type == "string" -%}
char*
{%- elif type == "string[]" -%}
char*[]
{%- elif type == "boolean" -%}
bool
{%- elif type == "int" -%}
int
{%- elif type == "double" -%}
double
{%- else -%}
{{type}}
{%- endif -%}
{%- endmacro %}
{%- macro print_value(type, value) -%}
{{ "\"" if type == "char*"}}{{value}}{{ "\"" if type == "char*"}}
{%- endmacro %}
{%- macro upFirst(text) -%}
{{ text[0]|upper}}{{text[1:] }}
{%- endmacro %}
{%- macro lowerFirst(text) -%}
{{ text[0]|lower}}{{text[1:] }}
{%- endmacro %}

/*
DO NOT EDIT, this is an Auto-generated file
from buildscripts/semantic-convention{{template}}
*/

/* clang-format off */

#pragma once

#include "opentelemetry/version.h"

OPENTELEMETRY_BEGIN_NAMESPACE
{{namespace_open}}

namespace {{class}}
{
/**
* The URL of the OpenTelemetry schema for these keys and values.
*/
static constexpr const char* SCHEMA_URL = "{{schemaUrl}}";
{%- for attribute in attributes if attribute.is_local and not attribute.ref %}

/**
* {{attribute.brief | render_markdown(code="{{@code {0}}}", paragraph="{0}")}}
{%- if attribute.note %}
*
* <p>Notes:
<ul> {{attribute.note | render_markdown(code="{{@code {0}}}", paragraph="<li>{0}</li>", list="{0}")}} </ul>
{%- endif %}
{%- if attribute.deprecated %}
*
* @deprecated {{attribute.deprecated | to_doc_brief}}.
{%- endif %}
*/
{%- if attribute.deprecated %}
@Deprecated
{%- endif %}
static constexpr const char* {{attribute.fqn | to_const_name}} = "{{attribute.fqn}}";
{%- endfor %}

// Enum definitions
{%- for attribute in attributes if attribute.is_local and not attribute.ref %}
{%- if attribute.is_enum %}
{%- set enum_name = attribute.fqn | to_camelcase(True) ~ "Values" %}
{%- set type = to_cpp_return_type(attribute.attr_type.enum_type) %}
namespace {{enum_name}}
{
{%- for member in attribute.attr_type.members %}
/** {% filter escape %}{{member.brief | to_doc_brief}}.{% endfilter %} */
static constexpr const {{ type }} {{ member.member_id | to_const_name }} = {{ print_value(type, member.value) }};
{%- endfor %}
}
{% endif %}
{%- endfor %}

{#
{%- if class == "SemanticAttributes" %}
// Manually defined and not YET in the YAML
/**
* The name of an event describing an exception.
*
* <p>Typically an event with that name should not be manually created. Instead {@link
* io.opentelemetry.api.trace.Span#recordException(Throwable)} should be used.
*/
static constexpr const char* EXCEPTION_EVENT_NAME = "exception";
{% endif %}
#}

} // namespace {{class}}
{{namespace_close}}
OPENTELEMETRY_END_NAMESPACE

/* clang-format on */

16 changes: 8 additions & 8 deletions examples/grpc/client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#include <iostream>
#include <memory>
#include <string>
#include "opentelemetry/trace/experimental_semantic_conventions.h"
#include "opentelemetry/trace/semantic_conventions.h"
#include "tracer_common.h"

using grpc::Channel;
Expand Down Expand Up @@ -46,11 +46,11 @@ class GreeterClient
std::string span_name = "GreeterClient/Greet";
auto span = get_tracer("grpc")->StartSpan(
span_name,
{{OTEL_GET_TRACE_ATTR(AttrRpcSystem), "grpc"},
{OTEL_GET_TRACE_ATTR(AttrRpcService), "grpc-example.GreetService"},
{OTEL_GET_TRACE_ATTR(AttrRpcMethod), "Greet"},
{OTEL_GET_TRACE_ATTR(AttrNetPeerIp), ip},
{OTEL_GET_TRACE_ATTR(AttrNetPeerPort), port}},
{{SemanticConventions::RPC_SYSTEM, "grpc"},
{SemanticConventions::RPC_SERVICE, "grpc-example.GreetService"},
{SemanticConventions::RPC_METHOD, "Greet"},
{SemanticConventions::NET_PEER_IP, ip},
{SemanticConventions::NET_PEER_PORT, port}},
options);

auto scope = get_tracer("grpc-client")->WithActiveSpan(span);
Expand All @@ -66,7 +66,7 @@ class GreeterClient
if (status.ok())
{
span->SetStatus(StatusCode::kOk);
span->SetAttribute(OTEL_GET_TRACE_ATTR(AttrRpcGrpcStatusCode), status.error_code());
span->SetAttribute(SemanticConventions::RPC_GRPC_STATUS_CODE, status.error_code());
// Make sure to end your spans!
span->End();
return response.response();
Expand All @@ -75,7 +75,7 @@ class GreeterClient
{
std::cout << status.error_code() << ": " << status.error_message() << std::endl;
span->SetStatus(StatusCode::kError);
span->SetAttribute(OTEL_GET_TRACE_ATTR(AttrRpcGrpcStatusCode), status.error_code());
span->SetAttribute(SemanticConventions::RPC_GRPC_STATUS_CODE, status.error_code());
// Make sure to end your spans!
span->End();
return "RPC failed";
Expand Down
17 changes: 8 additions & 9 deletions examples/grpc/server.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#endif

#include "opentelemetry/trace/context.h"
#include "opentelemetry/trace/experimental_semantic_conventions.h"
#include "opentelemetry/trace/semantic_conventions.h"
#include "opentelemetry/trace/span_context_kv_iterable_view.h"
#include "tracer_common.h"

Expand Down Expand Up @@ -64,14 +64,13 @@ class GreeterServer final : public Greeter::Service
options.parent = GetSpan(new_context)->GetContext();

std::string span_name = "GreeterService/Greet";
auto span =
get_tracer("grpc")->StartSpan(span_name,
{{OTEL_GET_TRACE_ATTR(AttrRpcSystem), "grpc"},
{OTEL_GET_TRACE_ATTR(AttrRpcService), "GreeterService"},
{OTEL_GET_TRACE_ATTR(AttrRpcMethod), "Greet"},
{OTEL_GET_TRACE_ATTR(AttrRpcGrpcStatusCode), 0}},
options);
auto scope = get_tracer("grpc")->WithActiveSpan(span);
auto span = get_tracer("grpc")->StartSpan(span_name,
{{SemanticConventions::RPC_SYSTEM, "grpc"},
{SemanticConventions::RPC_SERVICE, "GreeterService"},
{SemanticConventions::RPC_METHOD, "Greet"},
{SemanticConventions::RPC_GRPC_STATUS_CODE, 0}},
options);
auto scope = get_tracer("grpc")->WithActiveSpan(span);

// Fetch and parse whatever HTTP headers we can from the gRPC request.
span->AddEvent("Processing client attributes");
Expand Down
10 changes: 5 additions & 5 deletions examples/http/client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

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

namespace
Expand All @@ -26,9 +26,9 @@ void sendRequest(const std::string &url)
std::string span_name = url_parser.path_;
auto span = get_tracer("http-client")
->StartSpan(span_name,
{{OTEL_GET_TRACE_ATTR(AttrHttpUrl), url_parser.url_},
{OTEL_GET_TRACE_ATTR(AttrHttpScheme), url_parser.scheme_},
{OTEL_GET_TRACE_ATTR(AttrHttpMethod), "GET"}},
{{SemanticConventions::HTTP_URL, url_parser.url_},
{SemanticConventions::HTTP_SCHEME, url_parser.scheme_},
{SemanticConventions::HTTP_METHOD, "GET"}},
options);
auto scope = get_tracer("http-client")->WithActiveSpan(span);

Expand All @@ -44,7 +44,7 @@ void sendRequest(const std::string &url)
{
// set span attributes
auto status_code = result.GetResponse().GetStatusCode();
span->SetAttribute(OTEL_GET_TRACE_ATTR(AttrHttpStatusCode), status_code);
span->SetAttribute(SemanticConventions::HTTP_STATUS_CODE, status_code);
result.GetResponse().ForEachHeader(
[&span](nostd::string_view header_name, nostd::string_view header_value) {
span->SetAttribute("http.header." + std::string(header_name.data()), header_value);
Expand Down
14 changes: 7 additions & 7 deletions examples/http/server.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

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

#include <iostream>
Expand Down Expand Up @@ -39,13 +39,13 @@ class RequestHandler : public HTTP_SERVER_NS::HttpRequestCallback
// start span with parent context extracted from http header
auto span = get_tracer("http-server")
->StartSpan(span_name,
{{OTEL_GET_TRACE_ATTR(AttrHttpServerName), server_name},
{OTEL_GET_TRACE_ATTR(AttrNetHostPort), server_port},
{OTEL_GET_TRACE_ATTR(AttrHttpMethod), request.method},
{OTEL_GET_TRACE_ATTR(AttrHttpScheme), "http"},
{OTEL_GET_TRACE_ATTR(AttrHttpRequestContentLength),
{{SemanticConventions::HTTP_SERVER_NAME, server_name},
{SemanticConventions::NET_HOST_PORT, server_port},
{SemanticConventions::HTTP_METHOD, request.method},
{SemanticConventions::HTTP_SCHEME, "http"},
{SemanticConventions::HTTP_REQUEST_CONTENT_LENGTH,
static_cast<uint64_t>(request.content.length())},
{OTEL_GET_TRACE_ATTR(AttrHttpClientIp), request.client}},
{SemanticConventions::HTTP_CLIENT_IP, request.client}},
options);

auto scope = get_tracer("http_server")->WithActiveSpan(span);
Expand Down
2 changes: 1 addition & 1 deletion exporters/jaeger/src/recordable.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

#include "opentelemetry/exporters/jaeger/recordable.h"
#include "opentelemetry/sdk/common/global_log_handler.h"
#include "opentelemetry/sdk/resource/experimental_semantic_conventions.h"
#include "opentelemetry/sdk/resource/semantic_conventions.h"

OPENTELEMETRY_BEGIN_NAMESPACE
namespace exporter
Expand Down
11 changes: 4 additions & 7 deletions exporters/otlp/test/otlp_log_recordable_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
# include <gtest/gtest.h>

# include "opentelemetry/exporters/otlp/otlp_log_recordable.h"
# include "opentelemetry/sdk/resource/experimental_semantic_conventions.h"
# include "opentelemetry/sdk/resource/resource.h"
# include "opentelemetry/sdk/resource/semantic_conventions.h"

OPENTELEMETRY_BEGIN_NAMESPACE
namespace exporter
Expand Down Expand Up @@ -104,20 +104,17 @@ TEST(OtlpLogRecordable, DefaultResource)
for (int i = 0; i < proto_resource.attributes_size(); i++)
{
auto attr = proto_resource.attributes(static_cast<int>(i));
if (attr.key() ==
opentelemetry::sdk::resource::attr(OTEL_CPP_CONST_HASHCODE(AttrTelemetrySdkLanguage)))
if (attr.key() == resource::SemanticConventions::TELEMETRY_SDK_LANGUAGE)
{
EXPECT_EQ(attr.value().string_value(), "cpp");
++found_resource_count;
}
else if (attr.key() ==
opentelemetry::sdk::resource::attr(OTEL_CPP_CONST_HASHCODE(AttrTelemetrySdkName)))
else if (attr.key() == resource::SemanticConventions::TELEMETRY_SDK_NAME)
{
EXPECT_EQ(attr.value().string_value(), "opentelemetry");
++found_resource_count;
}
else if (attr.key() ==
opentelemetry::sdk::resource::attr(OTEL_CPP_CONST_HASHCODE(AttrTelemetrySdkVersion)))
else if (attr.key() == resource::SemanticConventions::TELEMETRY_SDK_VERSION)
{
EXPECT_EQ(attr.value().string_value(), OPENTELEMETRY_SDK_VERSION);
++found_resource_count;
Expand Down
6 changes: 3 additions & 3 deletions exporters/zipkin/src/recordable.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// SPDX-License-Identifier: Apache-2.0

#include "opentelemetry/exporters/zipkin/recordable.h"
#include "opentelemetry/sdk/resource/experimental_semantic_conventions.h"
#include "opentelemetry/sdk/resource/semantic_conventions.h"

#include <map>
#include <string>
Expand Down Expand Up @@ -216,9 +216,9 @@ void Recordable::SetResource(const sdk::resource::Resource &resource) noexcept
{
// only service.name attribute is supported by specs as of now.
auto attributes = resource.GetAttributes();
if (attributes.find(OTEL_GET_RESOURCE_ATTR(AttrServiceName)) != attributes.end())
if (attributes.find(SemanticConventions::SERVICE_NAME) != attributes.end())
{
service_name_ = nostd::get<std::string>(attributes[OTEL_GET_RESOURCE_ATTR(AttrServiceName)]);
service_name_ = nostd::get<std::string>(attributes[SemanticConventions::SERVICE_NAME]);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
// https://github.com/open-telemetry/opentelemetry-specification/tree/v1.0.0/specification/resource/semantic_conventions
// and MAY will change in future.

#warning "This file is deprecated. Use opentelemetry/sdk/resource/semantic_conventions.h"

#pragma once

#include <type_traits>
Expand Down Expand Up @@ -138,4 +140,4 @@ inline const char *attr(uint32_t attr)
}
} // namespace resource
} // namespace sdk
OPENTELEMETRY_END_NAMESPACE
OPENTELEMETRY_END_NAMESPACE
Loading

0 comments on commit 15cf768

Please sign in to comment.