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 tracing #2577

Merged
merged 1 commit into from
Jul 17, 2023
Merged

Opentelemetry tracing #2577

merged 1 commit into from
Jul 17, 2023

Conversation

sbiscigl
Copy link
Contributor

Description of changes:

Creates a Smithy Reference Architecture interface for emitting traces and metrics. This will allow for client users to more easily monitor the telemetry of the SDK inside a running application to find metrics. We also provide a Open telemetry implementation of metrics and tracing so that a user could see immediate value. For example a user could configure the SDK as such

int main() {
    SDKOptions options;
    InitAPI(options);
    {
        S3ClientConfiguration configuration;
        configuration.telemetryProvider = OtelTelemetryProvider::CreateOtelProvider(
            opentelemetry::exporter::trace::OStreamSpanExporterFactory::Create(),
            std::make_unique<opentelemetry::exporter::metrics::OStreamMetricExporter>());
        auto s3 = Aws::MakeUnique<S3Client>("test-alloc", configuration);
        auto result = s3->ListBuckets();
        if (!result.IsSuccess()) {
            std::cout << "error:" << result.GetError().GetMessage() << "\n";
        }
        auto getObjResp = s3->GetObject(GetObjectRequest()
            .WithBucket("bucket-name")
            .WithKey("key-name"));
        if (!getObjResp.IsSuccess()) {
            std::cout << "error:" << getObjResp.GetError().GetMessage() << "\n";
        }
        // sleep for period metrics emitter
        std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    }
    ShutdownAPI(options);
}

and receive the following output

{
  name          : S3.ListBuckets
  trace_id      : 0cb806c50dced1d97384b3891f3876c6
  span_id       : 9f1da789275c1a3c
  tracestate    : 
  parent_span_id: 0000000000000000
  start         : 1689257478862356000
  duration      : 376816125
  description   : 
  span kind     : Client
  status        : Unset
  attributes    : 
        rpc.system: aws-api
        rpc.service: S3
        rpc.method: ListBuckets
  events        : 
  links         : 
  resources     : 
        service.name: unknown_service
        telemetry.sdk.language: cpp
        telemetry.sdk.name: opentelemetry
        telemetry.sdk.version: 1.10.0
  instr-lib     : S3
}
{
  name          : S3.GetObject
  trace_id      : 054a45ec564bd3de9051d3720a5c76b2
  span_id       : 7c65af6ee7dc05b7
  tracestate    : 
  parent_span_id: 0000000000000000
  start         : 1689257479239449000
  duration      : 359973208
  description   : 
  span kind     : Client
  status        : Unset
  attributes    : 
        rpc.system: aws-api
        rpc.service: S3
        rpc.method: GetObject
  events        : 
  links         : 
  resources     : 
        service.name: unknown_service
        telemetry.sdk.language: cpp
        telemetry.sdk.name: opentelemetry
        telemetry.sdk.version: 1.10.0
  instr-lib     : S3
}
{
  scope name    : S3
  schema url    : 
  version       : 
  start time    : Thu Jul 13 14:11:18 2023
  end time      : Thu Jul 13 14:11:19 2023
  instrument name       : smithy.client.deserialization_duration
  description   : 
  unit          : ms
  type     : HistogramPointData
  count     : 1
  sum     : 2
  min     : 2
  max     : 2
  buckets     : [0, 5, 10, 25, 50, 75, 100, 250, 500, 750, 1000, 2500, 5000, 7500, 10000, ]
  counts     : [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]
  attributes            : 
        rpc.method: ListBuckets
        rpc.service: S3
  resources     :
        service.name: unknown_service
        telemetry.sdk.language: cpp
        telemetry.sdk.name: opentelemetry
        telemetry.sdk.version: 1.10.0
  start time    : Thu Jul 13 14:11:18 2023
  end time      : Thu Jul 13 14:11:19 2023
  instrument name       : smithy.client.http.ssl_duration
  description   : 
  unit          : ms
  type     : HistogramPointData
  count     : 1
  sum     : 507
  min     : 507
  max     : 507
  buckets     : [0, 5, 10, 25, 50, 75, 100, 250, 500, 750, 1000, 2500, 5000, 7500, 10000, ]
  counts     : [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, ]
  attributes            : 
  resources     :
        service.name: unknown_service
        telemetry.sdk.language: cpp
        telemetry.sdk.name: opentelemetry
        telemetry.sdk.version: 1.10.0
  start time    : Thu Jul 13 14:11:18 2023
  end time      : Thu Jul 13 14:11:19 2023
  instrument name       : smithy.client.http.dns_duration
  description   : 
  unit          : ms
  type     : HistogramPointData
  count     : 1
  sum     : 27
  min     : 27
  max     : 27
  buckets     : [0, 5, 10, 25, 50, 75, 100, 250, 500, 750, 1000, 2500, 5000, 7500, 10000, ]
  counts     : [0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]
  attributes            : 
  resources     :
        service.name: unknown_service
        telemetry.sdk.language: cpp
        telemetry.sdk.name: opentelemetry
        telemetry.sdk.version: 1.10.0
  start time    : Thu Jul 13 14:11:18 2023
  end time      : Thu Jul 13 14:11:19 2023
  instrument name       : smithy.client.duration
  description   : 
  unit          : ms
  type     : HistogramPointData
  count     : 1
  sum     : 359
  min     : 359
  max     : 359
  buckets     : [0, 5, 10, 25, 50, 75, 100, 250, 500, 750, 1000, 2500, 5000, 7500, 10000, ]
  counts     : [0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, ]
  attributes            : 
        rpc.method: GetObject
        rpc.service: S3
  resources     :
        service.name: unknown_service
        telemetry.sdk.language: cpp
        telemetry.sdk.name: opentelemetry
        telemetry.sdk.version: 1.10.0
  start time    : Thu Jul 13 14:11:18 2023
  end time      : Thu Jul 13 14:11:19 2023
  instrument name       : smithy.client.http.connect_duration
  description   : 
  unit          : ms
  type     : HistogramPointData
  count     : 1
  sum     : 356
  min     : 356
  max     : 356
  buckets     : [0, 5, 10, 25, 50, 75, 100, 250, 500, 750, 1000, 2500, 5000, 7500, 10000, ]
  counts     : [0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, ]
  attributes            : 
        rpc.method: GetObject
        rpc.service: S3
  resources     :
        service.name: unknown_service
        telemetry.sdk.language: cpp
        telemetry.sdk.name: opentelemetry
        telemetry.sdk.version: 1.10.0
  start time    : Thu Jul 13 14:11:18 2023
  end time      : Thu Jul 13 14:11:19 2023
  instrument name       : smithy.client.serialization_duration
  description   : 
  unit          : ms
  type     : HistogramPointData
  count     : 1
  sum     : 0
  min     : 0
  max     : 2.22507e-308
  buckets     : [0, 5, 10, 25, 50, 75, 100, 250, 500, 750, 1000, 2500, 5000, 7500, 10000, ]
  counts     : [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]
  attributes            : 
        rpc.method: GetObject
        rpc.service: S3
  resources     :
        service.name: unknown_service
        telemetry.sdk.language: cpp
        telemetry.sdk.name: opentelemetry
        telemetry.sdk.version: 1.10.0
  start time    : Thu Jul 13 14:11:18 2023
  end time      : Thu Jul 13 14:11:19 2023
  instrument name       : smithy.client.attempts
  description   : 
  unit          : n
  type          : SumPointData
  value         : 1
  attributes            : 
        rpc.method: GetObject
        rpc.service: S3
  resources     :
        service.name: unknown_service
        telemetry.sdk.language: cpp
        telemetry.sdk.name: opentelemetry
        telemetry.sdk.version: 1.10.0
  start time    : Thu Jul 13 14:11:18 2023
  end time      : Thu Jul 13 14:11:19 2023
  instrument name       : smithy.client.service_call_duration
  description   : 
  unit          : ms
  type     : HistogramPointData
  count     : 1
  sum     : 357
  min     : 357
  max     : 357
  buckets     : [0, 5, 10, 25, 50, 75, 100, 250, 500, 750, 1000, 2500, 5000, 7500, 10000, ]
  counts     : [0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, ]
  attributes            : 
        rpc.method: GetObject
        rpc.service: S3
  resources     :
        service.name: unknown_service
        telemetry.sdk.language: cpp
        telemetry.sdk.name: opentelemetry
        telemetry.sdk.version: 1.10.0
  start time    : Thu Jul 13 14:11:18 2023
  end time      : Thu Jul 13 14:11:19 2023
  instrument name       : smithy.client.auth.signing_duration
  description   : 
  unit          : ms
  type     : HistogramPointData
  count     : 1
  sum     : 0
  min     : 0
  max     : 2.22507e-308
  buckets     : [0, 5, 10, 25, 50, 75, 100, 250, 500, 750, 1000, 2500, 5000, 7500, 10000, ]
  counts     : [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]
  attributes            : 
        rpc.method: GetObject
        rpc.service: S3
  resources     :
        service.name: unknown_service
        telemetry.sdk.language: cpp
        telemetry.sdk.name: opentelemetry
        telemetry.sdk.version: 1.10.0
  start time    : Thu Jul 13 14:11:18 2023
  end time      : Thu Jul 13 14:11:19 2023
  instrument name       : smithy.client.http.throughput
  description   : 
  unit          : bytes/s
  type     : HistogramPointData
  count     : 1
  sum     : 16
  min     : 16
  max     : 16
  buckets     : [0, 5, 10, 25, 50, 75, 100, 250, 500, 750, 1000, 2500, 5000, 7500, 10000, ]
  counts     : [0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]
  attributes            : 
  resources     :
        service.name: unknown_service
        telemetry.sdk.language: cpp
        telemetry.sdk.name: opentelemetry
        telemetry.sdk.version: 1.10.0
  start time    : Thu Jul 13 14:11:18 2023
  end time      : Thu Jul 13 14:11:19 2023
  instrument name       : smithy.client.resolve_endpoint_duration
  description   : 
  unit          : ms
  type     : HistogramPointData
  count     : 1
  sum     : 0
  min     : 0
  max     : 2.22507e-308
  buckets     : [0, 5, 10, 25, 50, 75, 100, 250, 500, 750, 1000, 2500, 5000, 7500, 10000, ]
  counts     : [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]
  attributes            : 
        rpc.method: GetObject
        rpc.service: S3
  resources     :
        service.name: unknown_service
        telemetry.sdk.language: cpp
        telemetry.sdk.name: opentelemetry
        telemetry.sdk.version: 1.10.0
}

While the above uses the OStream exporter, the SDK can be configured with any of the open telemetry exporters. In specific this can be used with the AWS Distro for OpenTelemetry to report metrics and traces straight to AWS.

Check all that applies:

  • Did a review by yourself.
  • Added proper tests to cover this PR. (If tests are not applicable, explain.)
  • Checked if this PR is a breaking (APIs have been changed) change.
  • Checked if this PR will not introduce cross-platform inconsistent behavior.
  • Checked if this PR would require a ReadMe/Wiki update.

Check which platforms you have built SDK on to verify the correctness of this PR.

  • Linux
  • Windows
  • Android
  • MacOS
  • IOS
  • Other Platforms

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

return AssociateCreatedArtifactOutcome(MakeRequest(request, endpointResolutionOutcome.GetResult(), Aws::Http::HttpMethod::HTTP_POST, Aws::Auth::SIGV4_SIGNER));
auto tracer = m_telemetryProvider->getTracer(this->GetServiceClientName(), {});
auto span = tracer->CreateSpan(Aws::String(this->GetServiceClientName()) + ".AssociateCreatedArtifact",
{{ "rpc.method", request.GetServiceRequestName() }, { "rpc.service", this->GetServiceClientName() }, { "rpc.system", "aws-api" }},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if this->GetServiceClientName() is used to get over-writable service name (that can be updated by customer to update user agent) - then good

otherwise, SERVICE_NAME static variable will serve this purpose.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I dont think we will be able to use SERVICE_NAME because we add the service name dimensions in XmlClient/JsonClient/AwsClient where it is not accessible. Also SERVICE_NAME and GetServiceClientName could and do return different values, and they are needed to be the same for dimensions to work correctly.

that function is defined as

inline virtual const char* GetServiceClientName() const { return m_serviceName.c_str(); }

so i think it is ok to leave as is, let me know what you think though

src/aws-cpp-sdk-core/include/smithy/tracing/TracingUtils.h Outdated Show resolved Hide resolved
src/aws-cpp-sdk-core/include/smithy/tracing/TracingUtils.h Outdated Show resolved Hide resolved
src/aws-cpp-sdk-core/include/smithy/tracing/TracingUtils.h Outdated Show resolved Hide resolved
src/aws-cpp-sdk-core/source/client/AWSClient.cpp Outdated Show resolved Hide resolved
Copy link
Contributor

@SergeyRyabinin SergeyRyabinin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good.
Please also add doc comments for classes and methods definitions in headers.

@sbiscigl sbiscigl force-pushed the opentelemetry-tracing branch 4 times, most recently from e5224e5 to 0521c7b Compare July 14, 2023 21:41
@sbiscigl sbiscigl marked this pull request as ready for review July 17, 2023 17:29
@sbiscigl sbiscigl merged commit 32d186c into main Jul 17, 2023
@sbiscigl sbiscigl deleted the opentelemetry-tracing branch July 17, 2023 17:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants