aws / aws-xray-sdk-node

The official AWS X-Ray SDK for Node.js.
Apache License 2.0
273 stars 156 forks source link

Communication bridge between Amazon x-ray sdk and Hapi #521

Open dimitardanailov opened 2 years ago

dimitardanailov commented 2 years ago

I've been working as a blockchain company. My manager wants to integrate: Amazon X-Ray. Our solution uses several microservices. Part of them are using: hapi.dev(https://hapi.dev). The others microservices don't have a framework. The system has several microservices with PURE nodejs implementation.

My question about: How we can use Amazon X Ray could be used if the technology stack is mix between hapi.dev services and pure nodejs implementation.

Why I'm asking my question:

The documentation started with the following paraghraph: The X-Ray SDK for Node.js is a library for Express web applications and Node.js Lambda functions that provides classes and methods for generating and sending trace data to the X-Ray daemon. Trace data includes information about incoming HTTP requests served by the application, and calls that the application makes to downstream services using the AWS SDK or HTTP clients.

https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-nodejs.html

dimitardanailov commented 2 years ago

I've found as a package: https://www.npmjs.com/package/aws-xray-sdk-hapi

I'd like to ask what's the recommendation by the official contributors ?

willarmiros commented 2 years ago

Hi @dimitardanailov, this package is hosted in our repo here, where you can find the docs for it: https://github.com/aws/aws-xray-sdk-node/tree/master/sdk_contrib/hapi

However it was contributed by the community and not officially supported by AWS. If you are just getting started with X-Ray, I would recommend checking out the AWS Distro for OpenTelemetry which you can get started with following this guide: https://aws-otel.github.io/docs/getting-started/js-sdk/trace-manual-instr

It supports sending data directly to X-Ray, and has Hapi instrumentation: https://github.com/open-telemetry/opentelemetry-js-contrib/tree/main/plugins/node/opentelemetry-instrumentation-hapi

dimitardanailov commented 2 years ago

@willarmiros

Thank you very much! I should discuss your proposal with my manager.

Meanwhile: I'd like ask you about this part of the source code:

// credentials only required if mTLS is configured on Collector instance
    credentials: grpc.credentials.createSsl(
      fs.readFileSync("./ca.crt"),
      fs.readFileSync("./client.key"),
      fs.readFileSync("./client.crt")
    )

The following lines are required ? I'm not sure what's mTLS. What's your recommendation.

dimitardanailov commented 2 years ago

@willarmiros

I've a question. I've used the documentation which you gave:

// sendingTraces.ts

const { BatchSpanProcessor } = require('@opentelemetry/sdk-trace-base');
const { NodeTracerProvider } = require('@opentelemetry/sdk-trace-node');
const { registerInstrumentations } = require('@opentelemetry/instrumentation');
const { HapiInstrumentation } = require('@opentelemetry/instrumentation-hapi');
const { detectResources, Resource } = require('@opentelemetry/resources');
const {
  SemanticResourceAttributes,
} = require('@opentelemetry/semantic-conventions');
const {
  OTLPTraceExporter,
} = require('@opentelemetry/exporter-trace-otlp-grpc');
const { AWSXRayPropagator } = require('@opentelemetry/propagator-aws-xray');
const { AWSXRayIdGenerator } = require('@opentelemetry/id-generator-aws-xray');
const { trace } = require('@opentelemetry/api');

const { DiagConsoleLogger, DiagLogLevel, diag } = require('@opentelemetry/api');

module.exports = (serviceName) => {
  // create a provider using the AWS ID Generator
  const tracerConfig = {
    idGenerator: new AWSXRayIdGenerator(),
    // any instrumentations can be declared here
    instrumentations: [],
    // any resources can be declared here
    resource: Resource.default().merge(
      new Resource({
        [SemanticResourceAttributes.SERVICE_NAME]: serviceName,
      })
    ),
  };

  const tracerProvider = new NodeTracerProvider(tracerConfig);

  // add OTLP exporter
  const otlpExporter = new OTLPTraceExporter({
    // port configured in the Collector config, defaults to 4317
    url: 'localhost:4317',
  });
  tracerProvider.addSpanProcessor(new BatchSpanProcessor(otlpExporter));

  // Register the tracer provider with an X-Ray propagator
  tracerProvider.register({
    propagator: new AWSXRayPropagator(),
  });

  registerInstrumentations({
    instrumentations: [new HapiInstrumentation()],
  });

  // Return an tracer instance
  return trace.getTracer('sample-instrumentation');
};

The usage is:

// for health check at AWS
server.route({
  method: "GET",
  path: "/",
  handler: (req, h) => {
    sendingTraces("Apollo");

    const date = new Date();

    return "API Server;" + date.toISOString();
  },
});

If I understand correctly If we want Amazon X-ray to track the request: We should implement and create: ADOT connector. localhost:4317 must be replaced with Public Address.

carolabadeer commented 1 year ago

Hi @dimitardanailov! Yes, localhost:4317 is the default ADOT collector endpoint and should be replaced with the address of where you have the ADOT collector running if it is not running at localhost:4317

The ADOT collector documentation also has detailed steps on configuring and running the collector on AWS platforms and Docker