From 8140780d1c785cb5e86e93bc34a2e47d7c3e2d62 Mon Sep 17 00:00:00 2001 From: Patrice Chalin Date: Mon, 14 Aug 2023 16:47:38 -0400 Subject: [PATCH] [CI] Add markdown check for normalized code-blocks + .md page fixes --- .markdownlint.json | 5 +- content/en/blog/2022/k8s-otel-expose/index.md | 1 - content/en/docs/collector/build-connector.md | 1 - content/en/docs/collector/scaling.md | 56 +++++++-------- content/en/docs/demo/services/accounting.md | 20 +++--- content/en/docs/demo/services/ad.md | 42 +++++------ content/en/docs/demo/services/cart.md | 10 +-- content/en/docs/demo/services/checkout.md | 72 +++++++++---------- content/en/docs/demo/services/currency.md | 42 +++++------ content/en/docs/demo/services/email.md | 18 ++--- content/en/docs/demo/services/frontend.md | 6 +- .../en/docs/demo/services/load-generator.md | 4 +- .../en/docs/demo/services/product-catalog.md | 54 +++++++------- content/en/docs/demo/services/quote.md | 32 ++++----- .../en/docs/demo/services/recommendation.md | 40 +++++------ content/en/docs/demo/services/shipping.md | 34 ++++----- content/en/docs/faas/lambda-collector.md | 14 ++-- .../instrumentation/erlang/getting-started.md | 20 +++--- .../en/docs/instrumentation/erlang/manual.md | 2 - .../docs/instrumentation/erlang/sampling.md | 2 - .../instrumentation/net/getting-started.md | 18 +++-- .../instrumentation/php/getting-started.md | 1 - content/en/docs/instrumentation/php/manual.md | 19 +++-- .../en/docs/instrumentation/swift/manual.md | 17 ++--- .../_md-rules/trim-code-block-and-unindent.js | 52 ++++++++++++++ gulp-src/_util.js | 14 ++++ gulp-src/lint-md.js | 53 +++++++++++++- package.json | 1 + 28 files changed, 378 insertions(+), 272 deletions(-) create mode 100644 gulp-src/_md-rules/trim-code-block-and-unindent.js diff --git a/.markdownlint.json b/.markdownlint.json index 9542d57b061..e4ae47bef74 100644 --- a/.markdownlint.json +++ b/.markdownlint.json @@ -6,5 +6,8 @@ "no-emphasis-as-header": false, "no-hard-tabs": false, "no-inline-html": false, - "no-trailing-punctuation": false + "no-trailing-punctuation": false, + "no-trailing-spaces": true, + "custom-rules-below-this-point": false, + "trim-code-block-and-unindent": true } diff --git a/content/en/blog/2022/k8s-otel-expose/index.md b/content/en/blog/2022/k8s-otel-expose/index.md index a0a67688681..3c6af7389b5 100644 --- a/content/en/blog/2022/k8s-otel-expose/index.md +++ b/content/en/blog/2022/k8s-otel-expose/index.md @@ -198,7 +198,6 @@ my-in-memory-query ClusterIP 10.245.91.239 otel-collector-app-collector ClusterIP 10.245.5.134 4317/TCP 5m otel-collector-app-collector-headless ClusterIP None 4317/TCP 5m otel-collector-app-collector-monitoring ClusterIP 10.245.116.38 8888/TCP 5m - ``` Finally, cert-manager is configured to automatically request TLS certificates diff --git a/content/en/docs/collector/build-connector.md b/content/en/docs/collector/build-connector.md index 398daa3cccb..85ab6f5f0bd 100644 --- a/content/en/docs/collector/build-connector.md +++ b/content/en/docs/collector/build-connector.md @@ -464,7 +464,6 @@ func (c *connectorImp) ConsumeTraces(ctx context.Context, td ptrace.Traces) erro } return nil } - ``` ## Using the Component diff --git a/content/en/docs/collector/scaling.md b/content/en/docs/collector/scaling.md index 105d7584a8c..39e30abe0f6 100644 --- a/content/en/docs/collector/scaling.md +++ b/content/en/docs/collector/scaling.md @@ -282,34 +282,34 @@ After the reconciliation, the OpenTelemetry Operator will convert the Collector’s configuration into the following: ```yaml - exporters: - logging: null - receivers: - prometheus: - config: - global: - scrape_interval: 1m - scrape_timeout: 10s - evaluation_interval: 1m - scrape_configs: - - job_name: otel-collector - honor_timestamps: true - scrape_interval: 10s - scrape_timeout: 10s - metrics_path: /metrics - scheme: http - follow_redirects: true - http_sd_configs: - - follow_redirects: false - url: http://collector-with-ta-targetallocator:80/jobs/otel-collector/targets?collector_id=$POD_NAME - service: - pipelines: - traces: - exporters: - - logging - processors: [] - receivers: - - prometheus +exporters: + logging: null + receivers: + prometheus: + config: + global: + scrape_interval: 1m + scrape_timeout: 10s + evaluation_interval: 1m + scrape_configs: + - job_name: otel-collector + honor_timestamps: true + scrape_interval: 10s + scrape_timeout: 10s + metrics_path: /metrics + scheme: http + follow_redirects: true + http_sd_configs: + - follow_redirects: false + url: http://collector-with-ta-targetallocator:80/jobs/otel-collector/targets?collector_id=$POD_NAME + service: + pipelines: + traces: + exporters: + - logging + processors: [] + receivers: + - prometheus ``` Note how the Operator added a `global` section and a `new http_sd_configs` to diff --git a/content/en/docs/demo/services/accounting.md b/content/en/docs/demo/services/accounting.md index 1378b02b4d5..014fc8105d5 100644 --- a/content/en/docs/demo/services/accounting.md +++ b/content/en/docs/demo/services/accounting.md @@ -40,15 +40,15 @@ ensure all spans are exported. This service makes that call as part of a deferred function in main ```go - tp, err := initTracerProvider() - if err != nil { - log.Fatal(err) +tp, err := initTracerProvider() +if err != nil { + log.Fatal(err) +} +defer func() { + if err := tp.Shutdown(context.Background()); err != nil { + log.Printf("Error shutting down tracer provider: %v", err) } - defer func() { - if err := tp.Shutdown(context.Background()); err != nil { - log.Printf("Error shutting down tracer provider: %v", err) - } - }() +}() ``` ### Adding Kafka ( Sarama ) auto-instrumentation @@ -58,6 +58,6 @@ Kafka topic. To instrument the Kafka client the ConsumerHandler implemented by the developer has to be wrapped. ```go - handler := groupHandler{} // implements sarama.ConsumerGroupHandler - wrappedHandler := otelsarama.WrapConsumerGroupHandler(&handler) +handler := groupHandler{} // implements sarama.ConsumerGroupHandler +wrappedHandler := otelsarama.WrapConsumerGroupHandler(&handler) ``` diff --git a/content/en/docs/demo/services/ad.md b/content/en/docs/demo/services/ad.md index db341a400d2..db69b880990 100644 --- a/content/en/docs/demo/services/ad.md +++ b/content/en/docs/demo/services/ad.md @@ -29,15 +29,15 @@ Within the execution of auto-instrumented code you can get current span from context. ```java - Span span = Span.current(); +Span span = Span.current(); ``` Adding attributes to a span is accomplished using `setAttribute` on the span object. In the `getAds` function multiples attribute are added to the span. ```java - span.setAttribute("app.ads.contextKeys", req.getContextKeysList().toString()); - span.setAttribute("app.ads.contextKeys.count", req.getContextKeysCount()); +span.setAttribute("app.ads.contextKeys", req.getContextKeysList().toString()); +span.setAttribute("app.ads.contextKeys.count", req.getContextKeysCount()); ``` ### Add span events @@ -47,7 +47,7 @@ In the `getAds` function an event with an attribute is added when an exception is caught. ```java - span.addEvent("Error", Attributes.of(AttributeKey.stringKey("exception.message"), e.getMessage())); +span.addEvent("Error", Attributes.of(AttributeKey.stringKey("exception.message"), e.getMessage())); ``` ### Setting span status @@ -57,7 +57,7 @@ accordingly using `setStatus` on the span object. In the `getAds` function the span status is set when an exception is caught. ```java - span.setStatus(StatusCode.ERROR); +span.setStatus(StatusCode.ERROR); ``` ### Create new spans @@ -68,22 +68,22 @@ into context using `Span.makeCurrent()`. The `getRandomAds` function will create a new span, set it into context, perform an operation, and finally end the span. ```java - // create and start a new span manually - Tracer tracer = GlobalOpenTelemetry.getTracer("adservice"); - Span span = tracer.spanBuilder("getRandomAds").startSpan(); - - // put the span into context, so if any child span is started the parent will be set properly - try (Scope ignored = span.makeCurrent()) { - - Collection allAds = adsMap.values(); - for (int i = 0; i < MAX_ADS_TO_SERVE; i++) { - ads.add(Iterables.get(allAds, random.nextInt(allAds.size()))); - } - span.setAttribute("app.ads.count", ads.size()); - - } finally { - span.end(); - } +// create and start a new span manually +Tracer tracer = GlobalOpenTelemetry.getTracer("adservice"); +Span span = tracer.spanBuilder("getRandomAds").startSpan(); + +// put the span into context, so if any child span is started the parent will be set properly +try (Scope ignored = span.makeCurrent()) { + + Collection allAds = adsMap.values(); + for (int i = 0; i < MAX_ADS_TO_SERVE; i++) { + ads.add(Iterables.get(allAds, random.nextInt(allAds.size()))); + } + span.setAttribute("app.ads.count", ads.size()); + +} finally { + span.end(); +} ``` ## Metrics diff --git a/content/en/docs/demo/services/cart.md b/content/en/docs/demo/services/cart.md index abd99a0beab..6d48d472ac2 100644 --- a/content/en/docs/demo/services/cart.md +++ b/content/en/docs/demo/services/cart.md @@ -44,7 +44,7 @@ Within the execution of auto-instrumented code you can get current span (activity) from context. ```cs - var activity = Activity.Current; +var activity = Activity.Current; ``` Adding attributes (tags in .NET) to a span (activity) is accomplished using @@ -53,9 +53,9 @@ Adding attributes (tags in .NET) to a span (activity) is accomplished using span. ```cs - activity?.SetTag("app.user.id", request.UserId); - activity?.SetTag("app.product.quantity", request.Item.Quantity); - activity?.SetTag("app.product.id", request.Item.ProductId); +activity?.SetTag("app.user.id", request.UserId); +activity?.SetTag("app.product.quantity", request.Item.Quantity); +activity?.SetTag("app.product.id", request.Item.ProductId); ``` ### Add span events @@ -65,7 +65,7 @@ object. In the `GetCart` function from `services/CartService.cs` a span event is added. ```cs - activity?.AddEvent(new("Fetch cart")); +activity?.AddEvent(new("Fetch cart")); ``` ## Metrics diff --git a/content/en/docs/demo/services/checkout.md b/content/en/docs/demo/services/checkout.md index b3c3e6a65b9..f889e113fb3 100644 --- a/content/en/docs/demo/services/checkout.md +++ b/content/en/docs/demo/services/checkout.md @@ -41,12 +41,12 @@ ensure all spans are exported. This service makes that call as part of a deferred function in main ```go - tp := initTracerProvider() - defer func() { - if err := tp.Shutdown(context.Background()); err != nil { - log.Printf("Error shutting down tracer provider: %v", err) - } - }() +tp := initTracerProvider() +defer func() { + if err := tp.Shutdown(context.Background()); err != nil { + log.Printf("Error shutting down tracer provider: %v", err) + } +}() ``` ### Adding gRPC auto-instrumentation @@ -55,10 +55,10 @@ This service receives gRPC requests, which are instrumented in the main function as part of the gRPC server creation. ```go - var srv = grpc.NewServer( - grpc.UnaryInterceptor(otelgrpc.UnaryServerInterceptor()), - grpc.StreamInterceptor(otelgrpc.StreamServerInterceptor()), - ) +var srv = grpc.NewServer( + grpc.UnaryInterceptor(otelgrpc.UnaryServerInterceptor()), + grpc.StreamInterceptor(otelgrpc.StreamServerInterceptor()), +) ``` This service will issue several outgoing gRPC calls, which are all instrumented @@ -81,12 +81,12 @@ be in turn be processed by other microservices. To instrument the Kafka client the Producer has to be wrapped after it has been created. ```go - saramaConfig := sarama.NewConfig() - producer, err := sarama.NewAsyncProducer(brokers, saramaConfig) - if err != nil { - return nil, err - } - producer = otelsarama.WrapAsyncProducer(saramaConfig, producer) +saramaConfig := sarama.NewConfig() +producer, err := sarama.NewAsyncProducer(brokers, saramaConfig) +if err != nil { + return nil, err +} +producer = otelsarama.WrapAsyncProducer(saramaConfig, producer) ``` ### Add attributes to auto-instrumented spans @@ -95,19 +95,19 @@ Within the execution of auto-instrumented code you can get current span from context. ```go - span := trace.SpanFromContext(ctx) +span := trace.SpanFromContext(ctx) ``` Adding attributes to a span is accomplished using `SetAttributes` on the span object. In the `PlaceOrder` function several attributes are added to the span. ```go - span.SetAttributes( - attribute.String("app.order.id", orderID.String()), shippingTrackingAttribute, - attribute.Float64("app.shipping.amount", shippingCostFloat), - attribute.Float64("app.order.amount", totalPriceFloat), - attribute.Int("app.order.items.count", len(prep.orderItems)), - ) +span.SetAttributes( + attribute.String("app.order.id", orderID.String()), shippingTrackingAttribute, + attribute.Float64("app.shipping.amount", shippingCostFloat), + attribute.Float64("app.order.amount", totalPriceFloat), + attribute.Int("app.order.items.count", len(prep.orderItems)), +) ``` ### Add span events @@ -119,14 +119,14 @@ attributes, others do not. Adding a span event without attributes: ```go - span.AddEvent("prepared") +span.AddEvent("prepared") ``` Adding a span event with additional attributes: ```go - span.AddEvent("charged", - trace.WithAttributes(attribute.String("app.payment.transaction.id", txID))) +span.AddEvent("charged", + trace.WithAttributes(attribute.String("app.payment.transaction.id", txID))) ``` ## Metrics @@ -156,12 +156,12 @@ ensure all records are exported. This service makes that call as part of a deferred function in main ```go - mp := initMeterProvider() - defer func() { - if err := mp.Shutdown(context.Background()); err != nil { - log.Printf("Error shutting down meter provider: %v", err) - } - }() +mp := initMeterProvider() +defer func() { + if err := mp.Shutdown(context.Background()); err != nil { + log.Printf("Error shutting down meter provider: %v", err) + } +}() ``` ### Adding golang runtime auto-instrumentation @@ -169,10 +169,10 @@ deferred function in main Golang runtime are instrumented in the main function ```go - err := runtime.Start(runtime.WithMinimumReadMemStatsInterval(time.Second)) - if err != nil { - log.Fatal(err) - } +err := runtime.Start(runtime.WithMinimumReadMemStatsInterval(time.Second)) +if err != nil { + log.Fatal(err) +} ``` ## Logs diff --git a/content/en/docs/demo/services/currency.md b/content/en/docs/demo/services/currency.md index 31bb67335ba..c5bce920300 100644 --- a/content/en/docs/demo/services/currency.md +++ b/content/en/docs/demo/services/currency.md @@ -48,15 +48,15 @@ you need to start and put it into active context using function. ```cpp - std::string span_name = "CurrencyService/Convert"; - auto span = - get_tracer("currencyservice")->StartSpan(span_name, - {{SemanticConventions::kRpcSystem, "grpc"}, - {SemanticConventions::kRpcService, "CurrencyService"}, - {SemanticConventions::kRpcMethod, "Convert"}, - {SemanticConventions::kRpcGrpcStatusCode, 0}}, - options); - auto scope = get_tracer("currencyservice")->WithActiveSpan(span); +std::string span_name = "CurrencyService/Convert"; +auto span = + get_tracer("currencyservice")->StartSpan(span_name, + {{SemanticConventions::kRpcSystem, "grpc"}, + {SemanticConventions::kRpcService, "CurrencyService"}, + {SemanticConventions::kRpcMethod, "Convert"}, + {SemanticConventions::kRpcGrpcStatusCode, 0}}, + options); +auto scope = get_tracer("currencyservice")->WithActiveSpan(span); ``` ### Adding attributes to spans @@ -64,8 +64,8 @@ function. You can add an attribute to a span using `Span->SetAttribute(key, value)`. ```cpp - span->SetAttribute("app.currency.conversion.from", from_code); - span->SetAttribute("app.currency.conversion.to", to_code); +span->SetAttribute("app.currency.conversion.from", from_code); +span->SetAttribute("app.currency.conversion.to", to_code); ``` ### Add span events @@ -73,7 +73,7 @@ You can add an attribute to a span using `Span->SetAttribute(key, value)`. Adding span events is accomplished using `Span->AddEvent(name)`. ```cpp - span->AddEvent("Conversion successful, response sent back"); +span->AddEvent("Conversion successful, response sent back"); ``` ### Set span status @@ -82,7 +82,7 @@ Make sure to set your span status to `Ok`, or `Error` accordingly. You can do this using `Span->SetStatus(status)` ```cpp - span->SetStatus(StatusCode::kOk); +span->SetStatus(StatusCode::kOk); ``` ### Tracing context propagation @@ -126,14 +126,14 @@ This class is leveraged in the `Convert` method to extract context and create a creating new spans. ```cpp - StartSpanOptions options; - options.kind = SpanKind::kServer; - GrpcServerCarrier carrier(context); - - auto prop = context::propagation::GlobalTextMapPropagator::GetGlobalPropagator(); - auto current_ctx = context::RuntimeContext::GetCurrent(); - auto new_context = prop->Extract(carrier, current_ctx); - options.parent = GetSpan(new_context)->GetContext(); +StartSpanOptions options; +options.kind = SpanKind::kServer; +GrpcServerCarrier carrier(context); + +auto prop = context::propagation::GlobalTextMapPropagator::GetGlobalPropagator(); +auto current_ctx = context::RuntimeContext::GetCurrent(); +auto new_context = prop->Extract(carrier, current_ctx); +options.parent = GetSpan(new_context)->GetContext(); ``` ## Metrics diff --git a/content/en/docs/demo/services/email.md b/content/en/docs/demo/services/email.md index 498e941b290..f3a07e27aff 100644 --- a/content/en/docs/demo/services/email.md +++ b/content/en/docs/demo/services/email.md @@ -40,23 +40,23 @@ Within the execution of auto-instrumented code you can get current span from context. ```ruby - current_span = OpenTelemetry::Trace.current_span +current_span = OpenTelemetry::Trace.current_span ``` Adding multiple attributes to a span is accomplished using `add_attributes` on the span object. ```ruby - current_span.add_attributes({ - "app.order.id" => data.order.order_id, - }) +current_span.add_attributes({ + "app.order.id" => data.order.order_id, +}) ``` Adding only a single attribute can be accomplished using `set_attribute` on the span object. ```ruby - span.set_attribute("app.email.recipient", data.email) +span.set_attribute("app.email.recipient", data.email) ``` ### Create new spans @@ -66,10 +66,10 @@ OpenTelemetry Tracer object. When used in conjunction with a `do..end` block, the span will automatically be ended when the block ends execution. ```ruby - tracer = OpenTelemetry.tracer_provider.tracer('emailservice') - tracer.in_span("send_email") do |span| - # logic in context of span here - end +tracer = OpenTelemetry.tracer_provider.tracer('emailservice') +tracer.in_span("send_email") do |span| + # logic in context of span here +end ``` ## Metrics diff --git a/content/en/docs/demo/services/frontend.md b/content/en/docs/demo/services/frontend.md index ed5dd968ed9..826ea7420f2 100644 --- a/content/en/docs/demo/services/frontend.md +++ b/content/en/docs/demo/services/frontend.md @@ -85,9 +85,9 @@ This can be done in the `scripts.start` section of `package.json` and starting the application using `npm start`. ```json - "scripts": { - "start": "node --require ./Instrumentation.js server.js", - }, +"scripts": { + "start": "node --require ./Instrumentation.js server.js", +}, ``` ## Traces diff --git a/content/en/docs/demo/services/load-generator.md b/content/en/docs/demo/services/load-generator.md index 7c276725512..48da9954f2c 100644 --- a/content/en/docs/demo/services/load-generator.md +++ b/content/en/docs/demo/services/load-generator.md @@ -65,6 +65,6 @@ a context object containing the baggage item, and associating that context for all tasks by the load generator. ```python - ctx = baggage.set_baggage("synthetic_request", "true") - context.attach(ctx) +ctx = baggage.set_baggage("synthetic_request", "true") +context.attach(ctx) ``` diff --git a/content/en/docs/demo/services/product-catalog.md b/content/en/docs/demo/services/product-catalog.md index 9d3f99a6a7c..fa86f940f8d 100644 --- a/content/en/docs/demo/services/product-catalog.md +++ b/content/en/docs/demo/services/product-catalog.md @@ -42,12 +42,12 @@ ensure all spans are exported. This service makes that call as part of a deferred function in main ```go - tp := InitTracerProvider() - defer func() { - if err := tp.Shutdown(context.Background()); err != nil { - log.Fatalf("Tracer Provider Shutdown: %v", err) - } - }() +tp := InitTracerProvider() +defer func() { + if err := tp.Shutdown(context.Background()); err != nil { + log.Fatalf("Tracer Provider Shutdown: %v", err) + } +}() ``` ### Adding gRPC auto-instrumentation @@ -56,10 +56,10 @@ This service receives gRPC requests, which are instrumented in the main function as part of the gRPC server creation. ```go - srv := grpc.NewServer( - grpc.UnaryInterceptor(otelgrpc.UnaryServerInterceptor()), - grpc.StreamInterceptor(otelgrpc.StreamServerInterceptor()), - ) +srv := grpc.NewServer( + grpc.UnaryInterceptor(otelgrpc.UnaryServerInterceptor()), + grpc.StreamInterceptor(otelgrpc.StreamServerInterceptor()), +) ``` This service will issue outgoing gRPC calls, which are all instrumented by @@ -81,7 +81,7 @@ Within the execution of auto-instrumented code you can get current span from context. ```go - span := trace.SpanFromContext(ctx) +span := trace.SpanFromContext(ctx) ``` Adding attributes to a span is accomplished using `SetAttributes` on the span @@ -89,9 +89,9 @@ object. In the `GetProduct` function an attribute for the product ID is added to the span. ```go - span.SetAttributes( - attribute.String("app.product.id", req.Id), - ) +span.SetAttributes( + attribute.String("app.product.id", req.Id), +) ``` ### Setting span status @@ -101,8 +101,8 @@ an error condition, the span status is set accordingly using `SetStatus` on the span object. You can see this in the `GetProduct` function. ```go - msg := fmt.Sprintf("Error: ProductCatalogService Fail Feature Flag Enabled") - span.SetStatus(otelcodes.Error, msg) +msg := fmt.Sprintf("Error: ProductCatalogService Fail Feature Flag Enabled") +span.SetStatus(otelcodes.Error, msg) ``` ### Add span events @@ -112,7 +112,7 @@ Adding span events is accomplished using `AddEvent` on the span object. In the or when a product is successfully found. ```go - span.AddEvent(msg) +span.AddEvent(msg) ``` ## Metrics @@ -142,12 +142,12 @@ ensure all records are exported. This service makes that call as part of a deferred function in main. ```go - mp := initMeterProvider() - defer func() { - if err := mp.Shutdown(context.Background()); err != nil { - log.Fatalf("Error shutting down meter provider: %v", err) - } - }() +mp := initMeterProvider() +defer func() { + if err := mp.Shutdown(context.Background()); err != nil { + log.Fatalf("Error shutting down meter provider: %v", err) + } +}() ``` ### Adding golang runtime auto-instrumentation @@ -155,10 +155,10 @@ deferred function in main. Golang runtime is instrumented in the main function ```go - err := runtime.Start(runtime.WithMinimumReadMemStatsInterval(time.Second)) - if err != nil { - log.Fatal(err) - } +err := runtime.Start(runtime.WithMinimumReadMemStatsInterval(time.Second)) +if err != nil { + log.Fatal(err) +} ``` ## Logs diff --git a/content/en/docs/demo/services/quote.md b/content/en/docs/demo/services/quote.md index 9f79fd87a38..facaa44056c 100644 --- a/content/en/docs/demo/services/quote.md +++ b/content/en/docs/demo/services/quote.md @@ -27,7 +27,7 @@ This is enabled by setting the environment variable `OTEL_PHP_AUTOLOAD_ENABLED=true`. ```php - require __DIR__ . '/../vendor/autoload.php'; +require __DIR__ . '/../vendor/autoload.php'; ``` There are multiple ways to create or obtain a `Tracer`, in this example we @@ -35,7 +35,7 @@ obtain one from the global tracer provider which was initialized above, as part of SDK autoloading: ```php - $tracer = Globals::tracerProvider()->getTracer('manual-instrumentation'); +$tracer = Globals::tracerProvider()->getTracer('manual-instrumentation'); ``` ### Manually creating spans @@ -44,13 +44,13 @@ Creating a span manually can be done via a `Tracer`. The span will be default be a child of the active span in the current execution context: ```php - $span = Globals::tracerProvider() - ->getTracer('manual-instrumentation') - ->spanBuilder('calculate-quote') - ->setSpanKind(SpanKind::KIND_INTERNAL) - ->startSpan(); - /* calculate quote */ - $span->end(); +$span = Globals::tracerProvider() + ->getTracer('manual-instrumentation') + ->spanBuilder('calculate-quote') + ->setSpanKind(SpanKind::KIND_INTERNAL) + ->startSpan(); +/* calculate quote */ +$span->end(); ``` ### Add span attributes @@ -58,7 +58,7 @@ a child of the active span in the current execution context: You can obtain the current span using `OpenTelemetry\API\Trace\Span`. ```php - $span = Span::getCurrent(); +$span = Span::getCurrent(); ``` Adding attributes to a span is accomplished using `setAttribute` on the span @@ -66,8 +66,8 @@ object. In the `calculateQuote` function 2 attributes are added to the `childSpan`. ```php - $childSpan->setAttribute('app.quote.items.count', $numberOfItems); - $childSpan->setAttribute('app.quote.cost.total', $quote); +$childSpan->setAttribute('app.quote.items.count', $numberOfItems); +$childSpan->setAttribute('app.quote.cost.total', $quote); ``` ### Add span events @@ -79,15 +79,15 @@ others do not. Adding a span event without attributes: ```php - $span->addEvent('Received get quote request, processing it'); +$span->addEvent('Received get quote request, processing it'); ``` Adding a span event with additional attributes: ```php - $span->addEvent('Quote processed, response sent back', [ - 'app.quote.cost.total' => $payload - ]); +$span->addEvent('Quote processed, response sent back', [ + 'app.quote.cost.total' => $payload +]); ``` ## Metrics diff --git a/content/en/docs/demo/services/recommendation.md b/content/en/docs/demo/services/recommendation.md index 168d7e85972..9c78a303c58 100644 --- a/content/en/docs/demo/services/recommendation.md +++ b/content/en/docs/demo/services/recommendation.md @@ -31,7 +31,7 @@ endpoints, resource attributes, and service name are automatically set by the OpenTelemetry auto instrumentor based on environment variables. ```python - tracer = trace.get_tracer_provider().get_tracer("recommendationservice") +tracer = trace.get_tracer_provider().get_tracer("recommendationservice") ``` ### Add attributes to auto-instrumented spans @@ -40,14 +40,14 @@ Within the execution of auto-instrumented code you can get current span from context. ```python - span = trace.get_current_span() +span = trace.get_current_span() ``` Adding attributes to a span is accomplished using `set_attribute` on the span object. In the `ListRecommendations` function an attribute is added to the span. ```python - span.set_attribute("app.products_recommended.count", len(prod_list)) +span.set_attribute("app.products_recommended.count", len(prod_list)) ``` ### Create new spans @@ -58,7 +58,7 @@ conjunction with a `with` block, the span will automatically be ended when the block ends execution. This is done in the `get_product_list` function. ```python - with tracer.start_as_current_span("get_product_list") as span: +with tracer.start_as_current_span("get_product_list") as span: ``` ## Metrics @@ -71,7 +71,7 @@ name are automatically set by the OpenTelemetry auto instrumentor based on environment variables. ```python - meter = metrics.get_meter_provider().get_meter("recommendationservice") +meter = metrics.get_meter_provider().get_meter("recommendationservice") ``` ### Custom metrics @@ -101,20 +101,20 @@ a logging handler. Finally, it creates a logger for use throughout the application. ```python - logger_provider = LoggerProvider( - resource=Resource.create( - { - 'service.name': service_name, - } - ), - ) - set_logger_provider(logger_provider) - log_exporter = OTLPLogExporter(insecure=True) - logger_provider.add_log_record_processor(BatchLogRecordProcessor(log_exporter)) - handler = LoggingHandler(level=logging.NOTSET, logger_provider=logger_provider) - - logger = logging.getLogger('main') - logger.addHandler(handler) +logger_provider = LoggerProvider( + resource=Resource.create( + { + 'service.name': service_name, + } + ), +) +set_logger_provider(logger_provider) +log_exporter = OTLPLogExporter(insecure=True) +logger_provider.add_log_record_processor(BatchLogRecordProcessor(log_exporter)) +handler = LoggingHandler(level=logging.NOTSET, logger_provider=logger_provider) + +logger = logging.getLogger('main') +logger.addHandler(handler) ``` ### Create log records @@ -123,7 +123,7 @@ Create logs using the logger. Examples can be found in `ListRecommendations` and `get_product_list` functions. ```python - logger.info(f"Receive ListRecommendations for product ids:{prod_list}") +logger.info(f"Receive ListRecommendations for product ids:{prod_list}") ``` As you can see, after the initialization, log records can be created in the same diff --git a/content/en/docs/demo/services/shipping.md b/content/en/docs/demo/services/shipping.md index 995253c2ce7..d3e7cdeecba 100644 --- a/content/en/docs/demo/services/shipping.md +++ b/content/en/docs/demo/services/shipping.md @@ -123,10 +123,10 @@ implemented in the client middleware making use of the available `reqwest-middleware`, `reqwest-tracing` and `tracing-opentelemetry` libraries: ```rust - let reqwest_client = reqwest::Client::new(); - let client = ClientBuilder::new(reqwest_client) - .with(TracingMiddleware::::new()) - .build(); +let reqwest_client = reqwest::Client::new(); +let client = ClientBuilder::new(reqwest_client) + .with(TracingMiddleware::::new()) + .build(); ``` ### Add span attributes @@ -142,22 +142,22 @@ See below for a snippet from `shiporder` that holds context and a span in scope. This is appropriate in our case of a sync runtime. ```rust - let parent_cx = - global::get_text_map_propagator(|prop| prop.extract(&MetadataMap(request.metadata()))); - // in this case, generating a tracking ID is trivial - // we'll create a span and associated events all in this function. - let tracer = global::tracer("shippingservice"); - let mut span = tracer - .span_builder("hipstershop.ShippingService/ShipOrder").with_kind(SpanKind::Server).start_with_context(&tracer, &parent_cx); +let parent_cx = +global::get_text_map_propagator(|prop| prop.extract(&MetadataMap(request.metadata()))); +// in this case, generating a tracking ID is trivial +// we'll create a span and associated events all in this function. +let tracer = global::tracer("shippingservice"); +let mut span = tracer + .span_builder("hipstershop.ShippingService/ShipOrder").with_kind(SpanKind::Server).start_with_context(&tracer, &parent_cx); ``` You must add attributes to a span in context with `set_attribute`, followed by a `KeyValue` object, containing a key, and value. ```rust - let tid = create_tracking_id(); - span.set_attribute(KeyValue::new("app.shipping.tracking.id", tid.clone())); - info!("Tracking ID Created: {}", tid); +let tid = create_tracking_id(); +span.set_attribute(KeyValue::new("app.shipping.tracking.id", tid.clone())); +info!("Tracking ID Created: {}", tid); ``` ### Add span events @@ -170,9 +170,9 @@ events on spans. Attributes are not included here, but are Adding a span event: ```rust - let tid = create_tracking_id(); - span.set_attribute(KeyValue::new("app.shipping.tracking.id", tid.clone())); - info!("Tracking ID Created: {}", tid); +let tid = create_tracking_id(); +span.set_attribute(KeyValue::new("app.shipping.tracking.id", tid.clone())); +info!("Tracking ID Created: {}", tid); ``` ## Metrics diff --git a/content/en/docs/faas/lambda-collector.md b/content/en/docs/faas/lambda-collector.md index da350ac6c75..861fc4dc5c6 100644 --- a/content/en/docs/faas/lambda-collector.md +++ b/content/en/docs/faas/lambda-collector.md @@ -162,11 +162,11 @@ Loading configuration from S3 will require that the IAM role attached to your function includes read access to the relevant bucket. ```yaml - Function: - Type: AWS::Serverless::Function - Properties: - ... - Environment: - Variables: - OPENTELEMETRY_COLLECTOR_CONFIG_FILE: s3://.s3..amazonaws.com/collector_config.yaml +Function: + Type: AWS::Serverless::Function + Properties: + ... + Environment: + Variables: + OPENTELEMETRY_COLLECTOR_CONFIG_FILE: s3://.s3..amazonaws.com/collector_config.yaml ``` diff --git a/content/en/docs/instrumentation/erlang/getting-started.md b/content/en/docs/instrumentation/erlang/getting-started.md index 9148273ef8a..6ef95ca8479 100644 --- a/content/en/docs/instrumentation/erlang/getting-started.md +++ b/content/en/docs/instrumentation/erlang/getting-started.md @@ -166,26 +166,26 @@ random number. This seems like a pretty important operation, so in order to capture it in our trace we'll need to wrap it in a span. ```elixir - defp dice_roll do - Tracer.with_span("dice_roll") do - to_string(Enum.random(1..6)) - end +defp dice_roll do + Tracer.with_span("dice_roll") do + to_string(Enum.random(1..6)) end +end ``` It would also be nice to know what number it generated, so we can extract it as a local variable and add it as an attribute on the span. ```elixir - defp dice_roll do - Tracer.with_span("dice_roll") do - roll = Enum.random(1..6) +defp dice_roll do + Tracer.with_span("dice_roll") do + roll = Enum.random(1..6) - Tracer.set_attribute(:roll, roll) + Tracer.set_attribute(:roll, roll) - to_string(roll) - end + to_string(roll) end +end ``` Now if you point your browser/curl/etc. to diff --git a/content/en/docs/instrumentation/erlang/manual.md b/content/en/docs/instrumentation/erlang/manual.md index ba069d169d5..2c75b30e9d8 100644 --- a/content/en/docs/instrumentation/erlang/manual.md +++ b/content/en/docs/instrumentation/erlang/manual.md @@ -82,7 +82,6 @@ you can create [Spans](/docs/concepts/signals/traces/#spans). %% do work here. %% when this function returns the Span ends end). - ``` {{% /tab %}} {{% tab Elixir %}} @@ -118,7 +117,6 @@ child_function() -> fun() -> %% do work here. when this function returns, child will complete. end). - ``` {{% /tab %}} {{% tab Elixir %}} diff --git a/content/en/docs/instrumentation/erlang/sampling.md b/content/en/docs/instrumentation/erlang/sampling.md index c2c5edeab56..b520374142f 100644 --- a/content/en/docs/instrumentation/erlang/sampling.md +++ b/content/en/docs/instrumentation/erlang/sampling.md @@ -78,7 +78,6 @@ config :opentelemetry, sampler: {:parent_based, %{root: {:trace_id_ratio_based, remote_parent_not_sampled: :always_off, local_parent_sampled: :always_on, local_parent_not_sampled: :always_off}} - ``` {{% /tab %}} {{< /tabpane >}} @@ -128,7 +127,6 @@ config :opentelemetry, sampler: {:parent_based, %{root: :always_on, remote_parent_not_sampled: :always_off, local_parent_sampled: :always_on, local_parent_not_sampled: :always_off}} - ``` {{% /tab %}} {{< /tabpane >}} diff --git a/content/en/docs/instrumentation/net/getting-started.md b/content/en/docs/instrumentation/net/getting-started.md index 540b4657694..6e827524cc3 100644 --- a/content/en/docs/instrumentation/net/getting-started.md +++ b/content/en/docs/instrumentation/net/getting-started.md @@ -208,7 +208,6 @@ Value: Sum: 373.4504 Count: 1 Min: 373.4504 Max: 373.4504 (5000,7500]:0 (7500,10000]:0 (10000,+Infinity]:0 - ``` @@ -241,22 +240,21 @@ public static class DiagnosticsConfig public static Counter RequestCounter = Meter.CreateCounter("app.request_counter"); } - ``` Now we can increment the counter in our `Index` action. ```csharp - public IActionResult Index() - { - // do other stuff +public IActionResult Index() +{ + // do other stuff - DiagnosticsConfig.RequestCounter.Add(1, - new("Action", nameof(Index)), - new("Controller", nameof(HomeController))); + DiagnosticsConfig.RequestCounter.Add(1, + new("Action", nameof(Index)), + new("Controller", nameof(HomeController))); - return View(); - } + return View(); +} ``` You'll notice here that we're also adding Tags (OpenTelemetry Attributes) to our diff --git a/content/en/docs/instrumentation/php/getting-started.md b/content/en/docs/instrumentation/php/getting-started.md index c3ae7908e82..141d020855f 100644 --- a/content/en/docs/instrumentation/php/getting-started.md +++ b/content/en/docs/instrumentation/php/getting-started.md @@ -82,7 +82,6 @@ $app->get('/rolldice', function (Request $request, Response $response) { }); $app->run(); - ``` Run the application using the PHP built-in web server: diff --git a/content/en/docs/instrumentation/php/manual.md b/content/en/docs/instrumentation/php/manual.md index 29206c27cb7..a2609f1a203 100644 --- a/content/en/docs/instrumentation/php/manual.md +++ b/content/en/docs/instrumentation/php/manual.md @@ -206,16 +206,15 @@ For a method `parent` calling a method `child`, we can relate the spans by making the parent span active before creating the child span: ```php - - $parent = $tracer->spanBuilder("parent")->startSpan(); - $scope = $parent->activate(); - try { - $child = $tracer->spanBuilder("child")->startSpan(); - $child->end(); - } finally { - $parent->end(); - $scope->detach(); - } +$parent = $tracer->spanBuilder("parent")->startSpan(); +$scope = $parent->activate(); +try { + $child = $tracer->spanBuilder("child")->startSpan(); + $child->end(); +} finally { + $parent->end(); + $scope->detach(); +} ``` You _must_ `detach` the active scope if you have activated it. diff --git a/content/en/docs/instrumentation/swift/manual.md b/content/en/docs/instrumentation/swift/manual.md index 024b72db987..ae3b4a81282 100644 --- a/content/en/docs/instrumentation/swift/manual.md +++ b/content/en/docs/instrumentation/swift/manual.md @@ -41,13 +41,11 @@ OpenTelemetry.registerTracerProvider(tracerProvider: TracerProviderBuilder() .add(spanProcessor:SimpleSpanProcessor(spanExporter: traceExporter)) .with(resource: Resource()) .build()) - ``` A similar pattern is used for the OtlpMetricExporter: ```swift - // otlpConfiguration & grpcChannel can be reused OpenTelemetry.registerMeterProvider(meterProvider: MeterProviderBuilder() .with(processor: MetricProcessorSdk()) @@ -108,7 +106,6 @@ let childSpan = someTracer.spanBuilder(spanName: "child span") // do work childSpan.end() } - ``` The parent-child relationship will be automatically linked if `activeSpan` is @@ -129,7 +126,6 @@ func child() { // do work childSpan.end() } - ``` ### Getting the Current Span @@ -138,7 +134,7 @@ Sometimes it's useful to do something with the current/active span. Here's how to access the current span from an arbitrary point in your code. ```swift - let currentSpan = OpenTelemetry.instance.contextProvider.activeSpan +let currentSpan = OpenTelemetry.instance.contextProvider.activeSpan ``` ### Span Attributes @@ -163,11 +159,11 @@ Span, typically used to denote a meaningful, singular point in time during the Span’s duration. ```swift - let attributes = [ - "key" : AttributeValue.string("value"), - "result" : AttributeValue.int(100) - ] - span.addEvent(name: "computation complete", attributes: attributes) +let attributes = [ + "key" : AttributeValue.string("value"), + "result" : AttributeValue.int(100) +] +span.addEvent(name: "computation complete", attributes: attributes) ``` ### Setting Span Status @@ -250,7 +246,6 @@ OpenTelemetry.registerTracerProvider(tracerProvider: TracerProviderBuilder() .add(spanProcessor:SimpleSpanProcessor(spanExporter: StdoutExporter)) .with(resource: Resource()) .build()) - ``` The batch span processor allows for a variety of parameters for customization diff --git a/gulp-src/_md-rules/trim-code-block-and-unindent.js b/gulp-src/_md-rules/trim-code-block-and-unindent.js new file mode 100644 index 00000000000..9b83e0b292f --- /dev/null +++ b/gulp-src/_md-rules/trim-code-block-and-unindent.js @@ -0,0 +1,52 @@ +// Markdownlint custom rules + +const { trimBlankLinesFromArray } = require('../_util'); + +module.exports = { + names: ['trim-code-block-and-unindent'], + description: 'Code block avoid leading/trailing empty lines and unnecessary indentation', + tags: ['custom'], + function: (params, onError) => { + // const frontMatterLines = params.frontMatterLines; + + params.tokens.forEach(token => { + if (token.type === 'fence') { // Checking if it's a code block excluding plain text + const lines = token.content.split('\n'); + const originalNumLines = lines.length; + + let minIndent = Infinity; + for (const line of lines) { + if (line.trim().length > 0) { // Skip blank-only lines + const currentIndent = line.length - line.trimStart().length; + minIndent = Math.min(minIndent, currentIndent); + } + } + + let fixedLines = lines.map(line => { + if (line.trim().length === 0) return ''; // Blank-only lines + return line.substring(minIndent); // Unindent + }); + fixedLines = trimBlankLinesFromArray(fixedLines); + const fixedContent = fixedLines.join('\n'); + + if (token.content !== fixedContent + '\n') { + const offset = 1; // 1-based + const codeFenceLineCount = 1; + const args = { + lineNumber: token.map[0] + offset + codeFenceLineCount, + detail: 'Trim empty lines and/or unindent', + context: token.line, + fixInfo: { + // Using the following as an endLineNumber + lineNumber: token.map[0] + originalNumLines + offset - codeFenceLineCount, + insertText: fixedContent, + } + }; + // console.log(JSON.stringify(args, null, 2)); + // console.log(`${token.lineNumber} - Line ${token.map[0]} to ${token.map[1]}:`, token.content); + onError(args); + } + } + }); + } +}; diff --git a/gulp-src/_util.js b/gulp-src/_util.js index 98f3b43167a..8851edae775 100644 --- a/gulp-src/_util.js +++ b/gulp-src/_util.js @@ -7,3 +7,17 @@ exports.taskArgs = () => .help('info') // To avoid "task did not complete" errors, prevent help option from exiting .exitProcess(false); + +exports.trimBlankLinesFromArray = (lines) => { + // Remove leading empty lines + while (lines.length && !lines[0].trim()) { + lines.shift(); + } + + // Remove trailing empty lines + while (lines.length && !lines[lines.length - 1].trim()) { + lines.pop(); + } + + return lines; +} diff --git a/gulp-src/lint-md.js b/gulp-src/lint-md.js index 3bfa770e3bc..42d42bcc5d7 100644 --- a/gulp-src/lint-md.js +++ b/gulp-src/lint-md.js @@ -1,7 +1,9 @@ +const trimCodeBlockRule = require('./_md-rules/trim-code-block-and-unindent'); const gulp = require('gulp'); const through2 = require('through2'); const markdownlint = require('markdownlint'); -const { taskArgs } = require('./_util'); +const { taskArgs, trimBlankLinesFromArray } = require('./_util'); +const fs = require('fs'); const defaultGlob = '**/*.md'; const markdownFiles = [ @@ -16,6 +18,7 @@ const markdownFiles = [ let numFilesProcessed = 0, numFilesWithIssues = 0; +let fix = false; function markdownLintFile(file, encoding, callback) { const config = require('../.markdownlint.json'); @@ -34,6 +37,8 @@ function markdownLintFile(file, encoding, callback) { .replace(/\{\{[^\}]+\}\}/g, placeholder), }, config: config, + customRules: [trimCodeBlockRule], + // resultVersion: 3, }; markdownlint(options, function (err, result) { @@ -60,10 +65,50 @@ function markdownLintFile(file, encoding, callback) { // callback(new Error('...')); } numFilesProcessed++; + + if(fix) { + applyCustomRuleFixesHack(result); + } + callback(null, file); }); } +function applyCustomRuleFixesHack(result) { + Object.entries(result).forEach(([filePath, issues]) => { + let fileContent = fs.readFileSync(filePath, 'utf8'); + + // Sort issues by lineNumber in descending order + const sortedIssues = issues.sort((a, b) => b.lineNumber - a.lineNumber); + + sortedIssues.forEach(issue => { + if (issue.fixInfo) { + fileContent = applyFixesToFileContent(fileContent, issue); + } + }); + + fs.writeFileSync(filePath, fileContent, 'utf8'); + }); +} + +function applyFixesToFileContent(content, issue) { + // console.log(JSON.stringify(issue, null, 2)); + + const startLineNum = issue.lineNumber - 1; + const endLineNum = issue.ruleNames.includes("trim-code-block-and-unindent") ? + issue.fixInfo.lineNumber : startLineNum + 1; + const fixedLines = issue.fixInfo.insertText.split('\n'); + + // Remove lines that need fixing + const lines = content.split('\n'); + lines.splice(startLineNum, endLineNum - startLineNum); + + // Insert the fixed content + lines.splice(startLineNum, 0, ...fixedLines); + + return lines.join('\n'); +} + function lintMarkdown() { const argv = taskArgs().options({ glob: { @@ -72,12 +117,18 @@ function lintMarkdown() { description: 'Glob of files to run through markdownlint.', default: defaultGlob, }, + fix: { + type: 'boolean', + description: 'Automatically fix problems.', + default: false, + }, }).argv; if (argv.info) { // Info about options was already displayed by yargs.help(). return Promise.resolve(); } + fix = argv.fix; return gulp .src([argv.glob, ...markdownFiles]) diff --git a/package.json b/package.json index 7c258317d22..2e47ffa50ac 100644 --- a/package.json +++ b/package.json @@ -48,6 +48,7 @@ "fix:dict": "find content layouts -name \"*.md\" -print0 | xargs -0 ./scripts/normalize-cspell-front-matter.pl", "fix:filenames": "npm run _rename-to-kebab-case", "fix:format": "npm run format", + "fix:markdown": "npm run check:markdown -- --fix", "fix": "run-s fix:*", "format": "npm run _check:format -- --write", "get:submodule": "npm run _get:${GET:-submodule}",