Skip to content

Commit

Permalink
Adding semantic-convention attributes for resources (#872)
Browse files Browse the repository at this point in the history
  • Loading branch information
lalitb authored Jun 24, 2021
1 parent 2fd7bd2 commit ae6d810
Show file tree
Hide file tree
Showing 7 changed files with 334 additions and 44 deletions.
14 changes: 14 additions & 0 deletions api/include/opentelemetry/common/string_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,20 @@

#include "opentelemetry/nostd/string_view.h"

/** DJB2 hash function below is near-perfect hash used by several systems.
* Ref. http://www.cse.yorku.ca/~oz/hash.html
* </summary>
* <param name="str">String to hash</param>
* <param name="h">Initial offset</param>
* <returns>32 bit code</returns>
*/
constexpr uint32_t hashCode(const char *str, uint32_t h = 0)
{
return (uint32_t)(!str[h] ? 5381 : ((uint32_t)hashCode(str, h + 1) * (uint32_t)33) ^ str[h]);
}
#define OTEL_CPP_CONST_UINT32_T(x) std::integral_constant<uint32_t, (uint32_t)x>::value
#define OTEL_CPP_CONST_HASHCODE(name) OTEL_CPP_CONST_UINT32_T(hashCode(#name))

OPENTELEMETRY_BEGIN_NAMESPACE
namespace common
{
Expand Down
9 changes: 6 additions & 3 deletions exporters/jaeger/src/recordable.cc
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

#include <opentelemetry/exporters/jaeger/recordable.h>
#include "opentelemetry/exporters/jaeger/recordable.h"
#include "opentelemetry/sdk/resource/semantic_conventions.h"

OPENTELEMETRY_BEGIN_NAMESPACE
namespace exporter
{
namespace jaeger
{

using namespace opentelemetry::sdk::resource;

Recordable::Recordable() : span_{new thrift::Span} {}

void Recordable::PopulateAttribute(nostd::string_view key, const common::AttributeValue &value)
Expand Down Expand Up @@ -117,9 +120,9 @@ void Recordable::SetResource(const opentelemetry::sdk::resource::Resource &resou
{
// only service.name attribute is supported by specs as of now.
auto attributes = resource.GetAttributes();
if (attributes.find("service.name") != attributes.end())
if (attributes.find(OTEL_CPP_GET_ATTR(AttrServiceName)) != attributes.end())
{
service_name_ = nostd::get<std::string>(attributes["service.name"]);
service_name_ = nostd::get<std::string>(attributes[OTEL_CPP_GET_ATTR(AttrServiceName)]);
}
}

Expand Down
7 changes: 5 additions & 2 deletions exporters/zipkin/src/recordable.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// SPDX-License-Identifier: Apache-2.0

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

#include <map>
#include <string>
Expand All @@ -12,6 +13,8 @@ namespace exporter
namespace zipkin
{

using namespace opentelemetry::sdk::resource;

// constexpr needs keys to be constexpr, const is next best to use.
static const std::map<opentelemetry::trace::SpanKind, std::string> kSpanKindMap = {
{opentelemetry::trace::SpanKind::kClient, "CLIENT"},
Expand Down Expand Up @@ -208,9 +211,9 @@ void Recordable::SetResource(const opentelemetry::sdk::resource::Resource &resou
{
// only service.name attribute is supported by specs as of now.
auto attributes = resource.GetAttributes();
if (attributes.find("service.name") != attributes.end())
if (attributes.find(OTEL_CPP_GET_ATTR(AttrServiceName)) != attributes.end())
{
service_name_ = nostd::get<std::string>(attributes["service.name"]);
service_name_ = nostd::get<std::string>(attributes[OTEL_CPP_GET_ATTR(AttrServiceName)]);
}
}

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

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

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

OPENTELEMETRY_BEGIN_NAMESPACE
namespace sdk
{
namespace resource
{

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

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 "},

// telemetry attributes
{OTEL_CPP_CONST_HASHCODE(AttrTelemetrySdkName), "telemetry.sdk.name"},
{OTEL_CPP_CONST_HASHCODE(AttrTelemetrySdkLanguage), "telemetry.sdk.language"},
{OTEL_CPP_CONST_HASHCODE(AttrTelemetrySdkVersion), "telemetry.sdk.version"},
{OTEL_CPP_CONST_HASHCODE(AttrTelemetryAutoVersion), "telemetry.auto.version"},

// compute unit: container attributes
{OTEL_CPP_CONST_HASHCODE(AttrContainerName), "container.name"},
{OTEL_CPP_CONST_HASHCODE(AttrContainerId), "container.id"},
{OTEL_CPP_CONST_HASHCODE(AttrContainerRuntime), "container.runtime"},
{OTEL_CPP_CONST_HASHCODE(AttrContainerImageName), "container.image.name"},
{OTEL_CPP_CONST_HASHCODE(AttrContainerImageTag), "container.image.tag"},

// compute unit: faas attributes
{OTEL_CPP_CONST_HASHCODE(AttrFaasName), "faas.name"},
{OTEL_CPP_CONST_HASHCODE(AttrFaasId), "faas.id"},
{OTEL_CPP_CONST_HASHCODE(AttrFaasVersion), "faas.version"},
{OTEL_CPP_CONST_HASHCODE(AttrFaasInstance), "faas.instance"},
{OTEL_CPP_CONST_HASHCODE(AttrFaasMaxMemory), "faas.max_memory"},

// compute unit : process attributes
{OTEL_CPP_CONST_HASHCODE(AttrProcessId), "process.pid"},
{OTEL_CPP_CONST_HASHCODE(AttrProcessExecutableName), "process.executable.name"},
{OTEL_CPP_CONST_HASHCODE(AttrProcessExecutablePath), "process.executable.path"},
{OTEL_CPP_CONST_HASHCODE(AttrProcessCommand), "process.command"},
{OTEL_CPP_CONST_HASHCODE(AttrProcessCommandLine), "process.command_line"},
{OTEL_CPP_CONST_HASHCODE(AttrProcessCommandArgs), "process.command_args"},
{OTEL_CPP_CONST_HASHCODE(AttrProcessOwner), "process.owner"},

// compute : process runtimes
{OTEL_CPP_CONST_HASHCODE(AttrProcessRuntimeName), "process.runtime.name"},
{OTEL_CPP_CONST_HASHCODE(AttrProcessRuntimeVersion), "process.runtime.version"},
{OTEL_CPP_CONST_HASHCODE(AttrProcessRuntimeDescription), "process.runtime.description"},

// compute unit : WebEngine
{OTEL_CPP_CONST_HASHCODE(AttrWebEngineName), "webengine.name"},
{OTEL_CPP_CONST_HASHCODE(AttrWebEngineVersion), "webengine.version"},
{OTEL_CPP_CONST_HASHCODE(AttrWebEngineDescription), "webengine.description"},

// compute instance : host
{OTEL_CPP_CONST_HASHCODE(AttrHostId), "host.id"},
{OTEL_CPP_CONST_HASHCODE(AttrHostName), "host.name"},
{OTEL_CPP_CONST_HASHCODE(AttrHostType), "host.type"},
{OTEL_CPP_CONST_HASHCODE(AttrHostArch), "host.arch"},
{OTEL_CPP_CONST_HASHCODE(AttrHostImageName), "host.image.name"},
{OTEL_CPP_CONST_HASHCODE(AttrHostImageId), "host.image.id"},
{OTEL_CPP_CONST_HASHCODE(AttrHostImageVersion), "host.image.version"},

// env os attributes
{OTEL_CPP_CONST_HASHCODE(AttrOsType), "os.type"},
{OTEL_CPP_CONST_HASHCODE(AttrOsDescription), "os.description"},
{OTEL_CPP_CONST_HASHCODE(AttrOsName), "os.name"},
{OTEL_CPP_CONST_HASHCODE(AttrOsVersion), "os.version"},

// env device attributes
{OTEL_CPP_CONST_HASHCODE(AttrDeviceId), "device.id"},
{OTEL_CPP_CONST_HASHCODE(AttrDeviceModelIdentifier), "device.model.identifier"},
{OTEL_CPP_CONST_HASHCODE(AttrDeviceModelName), "device.model.name"},

// env cloud
{OTEL_CPP_CONST_HASHCODE(AttrCloudProvider), "cloud.provider"},
{OTEL_CPP_CONST_HASHCODE(AttrCloudAccountId), "cloud.account.id"},
{OTEL_CPP_CONST_HASHCODE(AttrCloudRegion), "cloud.region"},
{OTEL_CPP_CONST_HASHCODE(AttrCloudAvailabilityZone), "cloud.availability_zone"},
{OTEL_CPP_CONST_HASHCODE(AttrCloudPlatform), "cloud.platform"},

// env deployment
{OTEL_CPP_CONST_HASHCODE(AttrDeploymentEnvironment), "deployment.environment"},

// env kubernetes
// - cluster
{OTEL_CPP_CONST_HASHCODE(AttrK8sClusterName), "k8s.cluster.name"},
// - node
{OTEL_CPP_CONST_HASHCODE(AttrK8sNodeName), "k8s.node.name"},
{OTEL_CPP_CONST_HASHCODE(AttrK8sNodeUid), "k8s.node.uid"},
// - namespace
{OTEL_CPP_CONST_HASHCODE(AttrK8sNamespaceName), "k8s.namespace.name"},
// - pod
{OTEL_CPP_CONST_HASHCODE(AttrK8sPodUid), "k8s.pod.uid"},
{OTEL_CPP_CONST_HASHCODE(AttrK8sPodName), "k8s.pod.name"},
// - container
{OTEL_CPP_CONST_HASHCODE(AttrK8sContainerName), "k8s.container.name"},
// - replicaset
{OTEL_CPP_CONST_HASHCODE(AttrK8sReplicaSetUid), "k8s.replicaset.uid"},
{OTEL_CPP_CONST_HASHCODE(AttrK8sReplicaSetName), "k8s.replicaset.name"},
// - deployment
{OTEL_CPP_CONST_HASHCODE(AttrK8sDeploymentUid), "k8s.deployment.uid"},
{OTEL_CPP_CONST_HASHCODE(AttrK8sDeploymentName), "k8s.deployment.name"},
// - stateful-set
{OTEL_CPP_CONST_HASHCODE(AttrK8sStatefulSetUid), "k8s.statefulset.uid"},
{OTEL_CPP_CONST_HASHCODE(AttrK8sStatefulSetName), "k8s.statefulset.name"},
// - daemon set
{OTEL_CPP_CONST_HASHCODE(AttrK8sDaemonSetUid), "k8s.daemonset.uid"},
{OTEL_CPP_CONST_HASHCODE(AttrK8sDaemonSetName), "k8s.daemonset.name"},
// - job
{OTEL_CPP_CONST_HASHCODE(AttrK8sJobUid), "k8s.job.uid"},
{OTEL_CPP_CONST_HASHCODE(AttrK8sJobName), "k8s.job.name"},
// - cronjob
{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.
inline const char *attr(uint32_t attr)
{
return (attribute_ids.find(attr) != attribute_ids.end()) ? attribute_ids.at(attr) : "";
}
} // namespace resource
} // namespace sdk
OPENTELEMETRY_END_NAMESPACE
136 changes: 136 additions & 0 deletions sdk/include/opentelemetry/sdk/resource/semantic_conventions_old.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

#pragma once

#include "opentelemetry/version.h"

#define OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(attribute_name, attribute_value) \
static constexpr const char *GetAttribute##attribute_name() noexcept { return attribute_value; }

OPENTELEMETRY_BEGIN_NAMESPACE
namespace sdk
{
namespace resource
{
/**
* Stores the Constants for semantic Attribute names for resources outlined by the OpenTelemetry
* specifications. <see
* href,"https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/resource/semantic_conventions/README.md"/>.
*/

class SemanticConventions final
{

public:
// service attributes
OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(ServiceName, "service.name");
OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(ServiceNamespace, "service.namespace");
OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(ServiceInstance, "service.instance.id");
OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(ServiceVersion, "service.version ");

// telemetry attributes
OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(TelemetrySdkName, "telemetry.sdk.name");
OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(TelemetrySdkLanguage, "telemetry.sdk.language");
OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(TelemetrySdkVersion, "telemetry.sdk.version");
OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(TelemetryAutoVersion, "telemetry.auto.version");

// compute unit: container attributes
OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(ContainerName, "container.name");
OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(ContainerId, "container.id");
OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(ContainerRuntime, "container.runtime");
OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(ContainerImageName, "container.image.name");
OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(ContainerImageTag, "container.image.tag");

// compute unit: faas attributes
OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(FaasName, "faas.name");
OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(FaasId, "faas.id");
OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(FaasVersion, "faas.version");
OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(FaasInstance, "faas.instance");
OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(FaasMaxMemory, "faas.max_memory");

// compute unit : process attributes
OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(ProcessId, "process.pid");
OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(ProcessExecutableName, "process.executable.name");
OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(ProcessExecutablePath, "process.executable.path");
OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(ProcessCommand, "process.command");
OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(ProcessCommandLine, "process.command_line");
OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(ProcessCommandArgs, "process.command_args");
OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(ProcessOwner, "process.owner");

// compute : process runtimes
OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(ProcessRuntimeName, "process.runtime.name");
OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(ProcessRuntimeVersion, "process.runtime.version");
OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(ProcessRuntimeDescription, "process.runtime.description");

// compute unit : WebEngine
OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(WebEngineName, "webengine.name");
OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(WebEngineVersion, "webengine.version");
OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(WebEngineDescription, "webengine.description");

// compute instance : host
OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(HostId, "host.id");
OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(HostName, "host.name");
OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(HostType, "host.type");
OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(HostArch, "host.arch");
OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(HostImageName, "host.image.name");
OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(HostImageId, "host.image.id");
OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(HostImageVersion, "host.image.version");

// env os attributes
OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(OsType, "os.type");
OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(OsDescription, "os.description");
OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(OsName, "os.name");
OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(OsVersion, "os.version");

// env device attributes
OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(DeviceId, "device.id");
OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(DeviceModelIdentifier, "device.model.identifier");
OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(DeviceModelName, "device.model.name");

// env cloud
OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(CloudProvider, "cloud.provider");
OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(CloudAccountId, "cloud.account.id");
OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(CloudRegion, "cloud.region");
OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(CloudAvailabilityZone, "cloud.availability_zone");
OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(CloudPlatform, "cloud.platform");

// env deployment
OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(DeploymentEnvironment, "deployment.environment");

// env kubernetes
// - cluster
OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(K8sClusterName, "k8s.cluster.name");
// - node
OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(K8sNodeName, "k8s.node.name");
OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(K8sNodeUid, "k8s.node.uid");
// - namespace
OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(K8sNamespaceName, "k8s.namespace.name");
// - pod
OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(K8sPodUid, "k8s.pod.uid");
OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(K8sPodName, "k8s.pod.name");
// - container
OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(K8sContainerName, "k8s.container.name");
// - replicaset
OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(K8sReplicaSetUid, "k8s.replicaset.uid");
OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(K8sReplicaSetName, "k8s.replicaset.name");
// - deployment
OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(K8sDeploymentUid, "k8s.deployment.uid");
OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(K8sDeploymentName, "k8s.deployment.name");
// - stateful-set
OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(K8sStatefulSetUid, "k8s.statefulset.uid");
OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(K8sStatefulSetName, "k8s.statefulset.name");
// - daemon set
OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(K8sDaemonSetUid, "k8s.daemonset.uid");
OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(K8sDaemonSetName, "k8s.daemonset.name");
// - job
OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(K8sJobUid, "k8s.job.uid");
OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(K8sJobName, "k8s.job.name");
// - cronjob
OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(CronjobUid, "k8s.cronjob.id");
OTEL_RESOURCE_GENERATE_SEMCONV_METHOD(CronjobName, "k8s.cronjob.name");
};

} // namespace resource
} // namespace sdk
OPENTELEMETRY_END_NAMESPACE
15 changes: 9 additions & 6 deletions sdk/src/resource/resource.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "opentelemetry/sdk/resource/resource.h"
#include "opentelemetry/nostd/span.h"
#include "opentelemetry/sdk/resource/resource_detector.h"
#include "opentelemetry/sdk/resource/semantic_conventions.h"
#include "opentelemetry/version.h"

OPENTELEMETRY_BEGIN_NAMESPACE
Expand Down Expand Up @@ -32,15 +33,16 @@ Resource Resource::Create(const ResourceAttributes &attributes)
static auto otel_resource = OTELResourceDetector().Detect();
auto resource = Resource::GetDefault().Merge(otel_resource).Merge(Resource(attributes));

if (resource.attributes_.find(kServiceName) == resource.attributes_.end())
if (resource.attributes_.find(OTEL_CPP_GET_ATTR(AttrServiceName)) == resource.attributes_.end())
{
std::string default_service_name = "unknown_service";
auto it_process_executable_name = resource.attributes_.find(kProcessExecutableName);
auto it_process_executable_name =
resource.attributes_.find(OTEL_CPP_GET_ATTR(AttrProcessExecutableName));
if (it_process_executable_name != resource.attributes_.end())
{
default_service_name += ":" + nostd::get<std::string>(it_process_executable_name->second);
}
resource.attributes_[kServiceName] = default_service_name;
resource.attributes_[OTEL_CPP_GET_ATTR(AttrServiceName)] = default_service_name;
}
return resource;
}
Expand All @@ -53,9 +55,10 @@ Resource &Resource::GetEmpty()

Resource &Resource::GetDefault()
{
static Resource default_resource({{kTelemetrySdkLanguage, "cpp"},
{kTelemetrySdkName, "opentelemetry"},
{kTelemetrySdkVersion, OPENTELEMETRY_SDK_VERSION}});
static Resource default_resource(
{{OTEL_CPP_GET_ATTR(AttrTelemetrySdkLanguage), "cpp"},
{OTEL_CPP_GET_ATTR(AttrTelemetrySdkName), "opentelemetry"},
{OTEL_CPP_GET_ATTR(AttrTelemetrySdkVersion), OPENTELEMETRY_SDK_VERSION}});
return default_resource;
}

Expand Down
Loading

0 comments on commit ae6d810

Please sign in to comment.