diff --git a/.gitmodules b/.gitmodules index e89e163409df..f6d58ec4fe43 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,7 +1,7 @@ [submodule "themes/docsy"] path = themes/docsy url = https://github.com/google/docsy.git - docsy-pin = v0.10.0-2-g6f7e81d + docsy-pin = v0.10.0-6-g102892d docsy-note = "2024-04-01 Switching to google/docsy.git from cncf/docsy.git since we don't have any CNCF customizations." docsy-reminder = "Ensure that any tag referenced by `docsy-pin` is present in the remote repo (url), otherwise add (push) the tags to the repo." [submodule "content-modules/opentelemetry-specification"] diff --git a/assets/scss/_styles_project.scss b/assets/scss/_styles_project.scss index 560775b61ae4..f791ddcdcc96 100644 --- a/assets/scss/_styles_project.scss +++ b/assets/scss/_styles_project.scss @@ -184,7 +184,7 @@ } details { - background-color: $gray-100; + background-color: var(--bs-tertiary-bg); margin-bottom: 0.5em; summary { diff --git a/content/en/_index.md b/content/en/_index.md index 12a2ece429a2..34faed7154cf 100644 --- a/content/en/_index.md +++ b/content/en/_index.md @@ -3,13 +3,25 @@ title: OpenTelemetry description: >- High-quality, ubiquitous, and portable telemetry to enable effective observability -show_banner: true outputs: - HTML - REDIRECTS # Include this `content/en` ONLY developer_note: The blocks/cover shortcode (used below) will use as a background image any image file containing "background" in its name. +show_banner: true +limit_banner: 2 # Default to 2, adjust as needed +banners: + - message: + ' Join us for [**OTel Community Day** on + June + 25th](https://events.linuxfoundation.org/open-telemetry-community-day/)!' + to: 2024-06-25 + - message: + ' Help improve OTel and Prometheus + interoperability: [complete our + survey](https://forms.gle/bZAG9f7udoJsjZUG9) by May 31' + to: 2024-05-31 ---
diff --git a/content/en/community/end-user/_index.md b/content/en/community/end-user/_index.md index 3b95baef139a..584d363b9b36 100644 --- a/content/en/community/end-user/_index.md +++ b/content/en/community/end-user/_index.md @@ -10,9 +10,8 @@ about your implementation or adoption that you'd like to share with project contributors, or you want to help prioritize project issues. You've come to the right place! -- To connect with other end users and learn about upcoming events: - - Join the [Slack channel](slack-channel/) - - Join the [APAC end user discussion group](discussion-group/) +- To connect with other end users and learn about upcoming events, join the + [Slack channel](slack-channel/). - To learn about OpenTelemetry, check out: - [OTel in practice](otel-in-practice/) - Curated content on the @@ -54,5 +53,5 @@ OpenTelemetry. **I have questions about this, who can I reach out to?** You can find members of the -[OpenTelemetry End User SIG](https://github.com/open-telemetry/community/tree/main/working-groups/end-user) -in [#otel-sig-end-user](https://cloud-native.slack.com/archives/C01RT3MSWGZ). +[OpenTelemetry End User SIG](https://github.com/open-telemetry/sig-end-user) in +[#otel-sig-end-user](https://cloud-native.slack.com/archives/C01RT3MSWGZ). diff --git a/content/en/community/end-user/discussion-group.md b/content/en/community/end-user/discussion-group.md index f8459caadf1e..47f3be8bc625 100644 --- a/content/en/community/end-user/discussion-group.md +++ b/content/en/community/end-user/discussion-group.md @@ -5,46 +5,10 @@ description: Monthly OpenTelemetry usage discussions, all are welcome! weight: 20 --- -**As of April 2024, AMER and EMEA sessions are discontinued in favor of -discussion panels with a more targeted focus.** +**As of April 2024, discussion-group sessions are discontinued in favor of +end-user panels with a more targeted focus.** -Interested in learning how other end users are implementing OpenTelemetry in -their organizations? Come talk shop with other OpenTelemetry end users! This is -a vendor-neutral space to discuss best practices, ask questions, and meet other -observability-minded folks. - -Feedback that is shared and collected in these sessions will be routed back to -the relevant project maintainers to help drive prioritization of improvements -and changes to the project. - -## About - -- Search the blog for "End-User Discussions" to find summaries of past - discussions. -- A project maintainer and/or a Governance Committee member will be in - attendance at each session to provide additional context, insight, and plans - to user questions and feedback. -- Sessions are recorded. - -## Upcoming sessions - -Here are upcoming sessions, or you can view them on the -[OpenTelemetry calendar](https://github.com/open-telemetry/community#calendar): - -- **APAC (Asia Pacific)**: every third Wednesday of the month at 11AM India ST - (GMT +5.5), [register](https://lu.ma/1w129wgu) to get the Zoom link - - April 17 - - May 15 - - June 19 - -Past topics/questions have included: - -- Best practices on monitoring collectors in production -- Using OTel in CI/CD pipelines -- What’s holding you back from adopting more OpenTelemetry? -- Auto vs manual instrumentation use cases -- How to secure a publicly exposed OTel Collector? - -We use a [Lean Coffee](https://leancoffee.org) format where discussion topics -are generated and democratically selected by the group at the start of the -meeting. Topics are rigorously time-boxed by a facilitator. +If you would like to participate or help organize a future end-user panel, you +can find members of the +[OpenTelemetry End User SIG](https://github.com/open-telemetry/sig-end-user) in +[#otel-sig-end-user](https://cloud-native.slack.com/archives/C01RT3MSWGZ). diff --git a/content/en/docs/collector/configuration.md b/content/en/docs/collector/configuration.md index 4cf07ed66e9e..f815f86f6a20 100644 --- a/content/en/docs/collector/configuration.md +++ b/content/en/docs/collector/configuration.md @@ -602,95 +602,10 @@ service: ### Telemetry -The `telemetry` is where the telemetry for the Collector itself can be -configured. Collector's own telemetry can be useful when troubleshooting -Collector issues. It consists of two subsections: `logs` and `metrics`. - -The `logs` subsection lets you configure how the logs can be generated by the -Collector. By default, the Collector writes its logs to `stderr` with a log -level of `INFO`. You can also add static key-value pairs to all log entries with -the `initial_fields` to enrich the logging context. The [`logs` configuration -options](https://github.com/open-telemetry/opentelemetry-collector/blob/v{{% -param vers %}}/service/telemetry/config.go) are: - -- `level`: sets the minimum enabled logging level, default `INFO`. -- `development`: puts the logger in development mode, default `false`. -- `encoding`: sets the logger's encoding, default `console`. Example values are - `json`, `console`. -- `disable_caller`: stops annotating logs with the calling function's file name - and line number. By default `false`, all logs are annotated. -- `disable_stacktrace`: disables automatic stacktrace capturing, default - `false`. By default, stacktraces are captured for `WARN` level and above logs - in development and `ERROR` level and above in production. -- `sampling`: sets a sampling policy. -- `output_paths`: a list of URLs or file paths to write logging output to, - default `["stderr"]`. -- `error_output_paths`: a list of URLs or file paths to write logger errors to, - default `["stderr"]`. -- `initial_fields`: a collection of fields to add to the root logger. By - default, there is no initial field. - -The `metrics` subsection lets you configure how the metrics can be generated and -exposed by the Collector. By default, the Collector generates basic metrics -about itself and expose them for scraping at . -You can expose the endpoint to a specific or even all network interfaces when -needed. The [`metrics` configuration -options](https://github.com/open-telemetry/opentelemetry-collector/blob/v{{% -param vers %}}/service/telemetry/config.go) are: - -- `level`: the level of telemetry metrics, default `basic`. The possible values - are: - - `none`: no telemetry is collected. - - `basic`: essential service telemetry. - - `normal`: the default level, adds standard indicators on top of basic. - - `detailed`: the most verbose level, includes dimensions and views. -- `address`: the `[address]:port` formatted URL that metrics exposition should - be bound to. Default `127.0.0.1:8888`. - -The following example shows the Collector telemetry configuration: - -```yaml -service: - telemetry: - logs: - level: DEBUG - initial_fields: - service: my-instance - metrics: - level: detailed - address: 0.0.0.0:8888 -``` - -Note that it's possible to scrape the metrics by using a -[Prometheus receiver](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/receiver/prometheusreceiver) -within the Collector configuration so that we can consume the Collector's -metrics at the backend. For example: - -```yaml -receivers: - prometheus: - trim_metric_suffixes: true - use_start_time_metric: true - start_time_metric_regex: .* - config: - scrape_configs: - - job_name: 'otel-collector' - scrape_interval: 5s - static_configs: - - targets: ['127.0.0.1:8888'] - -exporters: - otlp: - endpoint: my.company.com:4317 - tls: - insecure: true - -service: - pipelines: - metrics: - receivers: [prometheus] - exporters: [otlp] -``` +The `telemetry` config section is where you can set up observability for the +Collector itself. It consists of two subsections: `logs` and `metrics`. To learn +how to configure these signals, see +[Activate internal telemetry in the Collector](/docs/collector/internal-telemetry#activate-internal-telemetry-in-the-collector). ## Other Information diff --git a/content/en/docs/collector/internal-telemetry.md b/content/en/docs/collector/internal-telemetry.md index 9405568798a1..3dfdad230978 100644 --- a/content/en/docs/collector/internal-telemetry.md +++ b/content/en/docs/collector/internal-telemetry.md @@ -1,12 +1,14 @@ --- title: Internal telemetry weight: 25 -cSpell:ignore: journalctl kube otecol pprof tracez zpages +# prettier-ignore +cSpell:ignore: alloc journalctl kube otecol pprof tracez underperforming zpages --- You can monitor the health of any OpenTelemetry Collector instance by checking -its own internal telemetry. Read on to learn how to configure this telemetry to -help you [troubleshoot](/docs/collector/troubleshooting/) Collector issues. +its own internal telemetry. Read on to learn about this telemetry and how to +configure it to help you [troubleshoot](/docs/collector/troubleshooting/) +Collector issues. ## Activate internal telemetry in the Collector @@ -31,30 +33,34 @@ Set the address in the config `service::telemetry::metrics`: service: telemetry: metrics: - address: '0.0.0.0:8888' + address: 0.0.0.0:8888 ``` -You can enhance the metrics telemetry level using the `level` field. The -following is a list of all possible values and their explanations. +You can adjust the verbosity of the Collector metrics output by setting the +`level` field to one of the following values: -- `none` indicates that no telemetry data should be collected. -- `basic` is the recommended value and covers the basics of the service - telemetry. -- `normal` adds other indicators on top of basic. -- `detailed` adds dimensions and views to the previous levels. +- `none`: no telemetry is collected. +- `basic`: essential service telemetry. +- `normal`: the default level, adds standard indicators on top of basic. +- `detailed`: the most verbose level, includes dimensions and views. -For example: +Each verbosity level represents a threshold at which certain metrics are +emitted. For the complete list of metrics, with a breakdown by level, see +[Lists of internal metrics](#lists-of-internal-metrics). + +The default level for metrics output is `normal`. To use another level, set +`service::telemetry::metrics::level`: ```yaml service: telemetry: metrics: level: detailed - address: ':8888' ``` -The Collector can also be configured to scrape its own metrics and send them -through configured pipelines. For example: +The Collector can also be configured to scrape its own metrics using a +[Prometheus receiver](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/receiver/prometheusreceiver) +and send them through configured pipelines. For example: ```yaml receivers: @@ -80,22 +86,35 @@ service: {{% alert title="Caution" color="warning" %}} -Self-monitoring is a risky practice. If an issue arises, the source of the -problem is unclear and the telemetry is unreliable. +When self-monitoring, the Collector collects its own telemetry and sends it to +the desired backend for analysis. This can be a risky practice. If the Collector +is underperforming, its self-monitoring capability could be impacted. As a +result, the self-monitored telemetry might not reach the backend in time for +critical analysis. {{% /alert %}} ### Configure internal logs -You can find log output in `stderr`. The verbosity level for logs defaults to -`INFO`, but you can adjust it in the config `service::telemetry::logs`: +Log output is found in `stderr`. You can configure logs in the config +`service::telemetry::logs`. The [configuration +options](https://github.com/open-telemetry/opentelemetry-collector/blob/v{{% +param vers %}}/service/telemetry/config.go) are: -```yaml -service: - telemetry: - logs: - level: 'debug' -``` +| Field name | Default value | Description | +| ---------------------- | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `level` | `INFO` | Sets the minimum enabled logging level. Other possible values are `DEBUG`, `WARN`, and `ERROR`. | +| `development` | `false` | Puts the logger in development mode. | +| `encoding` | `console` | Sets the logger's encoding. The other possible value is `json`. | +| `disable_caller` | `false` | Stops annotating logs with the calling function's file name and line number. By default, all logs are annotated. | +| `disable_stacktrace` | `false` | Disables automatic stacktrace capturing. Stacktraces are captured for logs at `WARN` level and above in development and at `ERROR` level and above in production. | +| `sampling::enabled` | `true` | Sets a sampling policy. | +| `sampling::tick` | `10s` | The interval in seconds that the logger applies to each sampling. | +| `sampling::initial` | `10` | The number of messages logged at the start of each `sampling::tick`. | +| `sampling::thereafter` | `100` | Sets the sampling policy for subsequent messages after `sampling::initial` messages are logged. When `sampling::thereafter` is set to `N`, every `Nth` message is logged and all others are dropped. If `N` is zero, the logger drops all messages after `sampling::initial` messages are logged. | +| `output_paths` | `["stderr"]` | A list of URLs or file paths to write logging output to. | +| `error_output_paths` | `["stderr"]` | A list of URLs or file paths to write logger errors to. | +| `initial_fields` | | A collection of static key-value pairs added to all log entries to enrich logging context. By default, there is no initial field. | You can also see logs for the Collector on a Linux systemd system using `journalctl`: @@ -113,3 +132,143 @@ journalctl | grep otelcol | grep Error ``` {{% /tab %}} {{< /tabpane >}} + +## Types of internal observability + +The OpenTelemetry Collector aims to be a model of observable service by clearly +exposing its own operational metrics. Additionally, it collects host resource +metrics that can help you understand if problems are caused by a different +process on the same host. Specific components of the Collector can also emit +their own custom telemetry. In this section, you will learn about the different +types of observability emitted by the Collector itself. + +### Values observable with internal metrics + +The Collector emits internal metrics for the following **current values**: + +- Resource consumption, including CPU, memory, and I/O. +- Data reception rate, broken down by receiver. +- Data export rate, broken down by exporters. +- Data drop rate due to throttling, broken down by data type. +- Data drop rate due to invalid data received, broken down by data type. +- Throttling state, including Not Throttled, Throttled by Downstream, and + Internally Saturated. +- Incoming connection count, broken down by receiver. +- Incoming connection rate showing new connections per second, broken down by + receiver. +- In-memory queue size in bytes and in units. +- Persistent queue size. +- End-to-end latency from receiver input to exporter output. +- Latency broken down by pipeline elements, including exporter network roundtrip + latency for request/response protocols. + +Rate values are averages over 10 second periods, measured in bytes/sec or +units/sec (for example, spans/sec). + +{{% alert title="Caution" color="warning" %}} + +Byte measurements can be expensive to compute. + +{{% /alert %}} + +The Collector also emits internal metrics for these **cumulative values**: + +- Total received data, broken down by receivers. +- Total exported data, broken down by exporters. +- Total dropped data due to throttling, broken down by data type. +- Total dropped data due to invalid data received, broken down by data type. +- Total incoming connection count, broken down by receiver. +- Uptime since start. + +### Lists of internal metrics + +The following tables group each internal metric by level of verbosity: `basic`, +`normal`, and `detailed`. Each metric is identified by name and description and +categorized by instrumentation type. + + + +#### `basic`-level metrics + +| Metric name | Description | Type | +| ------------------------------------------------------ | --------------------------------------------------------------------------------------- | --------- | +| `otelcol_exporter_enqueue_failed_`
`log_records` | Number of spans that exporter(s) failed to enqueue. | Counter | +| `otelcol_exporter_enqueue_failed_`
`metric_points` | Number of metric points that exporter(s) failed to enqueue. | Counter | +| `otelcol_exporter_enqueue_failed_`
`spans` | Number of spans that exporter(s) failed to enqueue. | Counter | +| `otelcol_exporter_queue_capacity` | Fixed capacity of the retry queue, in batches. | Gauge | +| `otelcol_exporter_queue_size` | Current size of the retry queue, in batches. | Gauge | +| `otelcol_exporter_send_failed_`
`log_records` | Number of logs that exporter(s) failed to send to destination. | Counter | +| `otelcol_exporter_send_failed_`
`metric_points` | Number of metric points that exporter(s) failed to send to destination. | Counter | +| `otelcol_exporter_send_failed_`
`spans` | Number of spans that exporter(s) failed to send to destination. | Counter | +| `otelcol_exporter_sent_log_records` | Number of logs successfully sent to destination. | Counter | +| `otelcol_exporter_sent_metric_points` | Number of metric points successfully sent to destination. | Counter | +| `otelcol_exporter_sent_spans` | Number of spans successfully sent to destination. | Counter | +| `otelcol_process_cpu_seconds` | Total CPU user and system time in seconds. | Counter | +| `otelcol_process_memory_rss` | Total physical memory (resident set size). | Gauge | +| `otelcol_process_runtime_heap_`
`alloc_bytes` | Bytes of allocated heap objects (see 'go doc runtime.MemStats.HeapAlloc'). | Gauge | +| `otelcol_process_runtime_total_`
`alloc_bytes` | Cumulative bytes allocated for heap objects (see 'go doc runtime.MemStats.TotalAlloc'). | Counter | +| `otelcol_process_runtime_total_`
`sys_memory_bytes` | Total bytes of memory obtained from the OS (see 'go doc runtime.MemStats.Sys'). | Gauge | +| `otelcol_process_uptime` | Uptime of the process. | Counter | +| `otelcol_processor_accepted_`
`log_records` | Number of logs successfully pushed into the next component in the pipeline. | Counter | +| `otelcol_processor_accepted_`
`metric_points` | Number of metric points successfully pushed into the next component in the pipeline. | Counter | +| `otelcol_processor_accepted_spans` | Number of spans successfully pushed into the next component in the pipeline. | Counter | +| `otelcol_processor_batch_batch_`
`send_size_bytes` | Number of bytes in the batch that was sent. | Histogram | +| `otelcol_processor_dropped_`
`log_records` | Number of logs dropped by the processor. | Counter | +| `otelcol_processor_dropped_`
`metric_points` | Number of metric points dropped by the processor. | Counter | +| `otelcol_processor_dropped_spans` | Number of spans dropped by the processor. | Counter | +| `otelcol_receiver_accepted_`
`log_records` | Number of logs successfully ingested and pushed into the pipeline. | Counter | +| `otelcol_receiver_accepted_`
`metric_points` | Number of metric points successfully ingested and pushed into the pipeline. | Counter | +| `otelcol_receiver_accepted_spans` | Number of spans successfully ingested and pushed into the pipeline. | Counter | +| `otelcol_receiver_refused_`
`log_records` | Number of logs that could not be pushed into the pipeline. | Counter | +| `otelcol_receiver_refused_`
`metric_points` | Number of metric points that could not be pushed into the pipeline. | Counter | +| `otelcol_receiver_refused_spans` | Number of spans that could not be pushed into the pipeline. | Counter | +| `otelcol_scraper_errored_`
`metric_points` | Number of metric points the Collector failed to scrape. | Counter | +| `otelcol_scraper_scraped_`
`metric_points` | Number of metric points scraped by the Collector. | Counter | + +#### Additional `normal`-level metrics + +| Metric name | Description | Type | +| ------------------------------------------------------- | --------------------------------------------------------------- | --------- | +| `otelcol_processor_batch_batch_`
`send_size` | Number of units in the batch. | Histogram | +| `otelcol_processor_batch_batch_`
`size_trigger_send` | Number of times the batch was sent due to a size trigger. | Counter | +| `otelcol_processor_batch_metadata_`
`cardinality` | Number of distinct metadata value combinations being processed. | Counter | +| `otelcol_processor_batch_timeout_`
`trigger_send` | Number of times the batch was sent due to a timeout trigger. | Counter | + +#### Additional `detailed`-level metrics + +| Metric name | Description | Type | +| --------------------------------- | ----------------------------------------------------------------------------------------- | --------- | +| `http_client_active_requests` | Number of active HTTP client requests. | Counter | +| `http_client_connection_duration` | Measures the duration of the successfully established outbound HTTP connections. | Histogram | +| `http_client_open_connections` | Number of outbound HTTP connections that are active or idle on the client. | Counter | +| `http_client_request_body_size` | Measures the size of HTTP client request bodies. | Histogram | +| `http_client_request_duration` | Measures the duration of HTTP client requests. | Histogram | +| `http_client_response_body_size` | Measures the size of HTTP client response bodies. | Histogram | +| `http_server_active_requests` | Number of active HTTP server requests. | Counter | +| `http_server_request_body_size` | Measures the size of HTTP server request bodies. | Histogram | +| `http_server_request_duration` | Measures the duration of HTTP server requests. | Histogram | +| `http_server_response_body_size` | Measures the size of HTTP server response bodies. | Histogram | +| `rpc_client_duration` | Measures the duration of outbound RPC. | Histogram | +| `rpc_client_request_size` | Measures the size of RPC request messages (uncompressed). | Histogram | +| `rpc_client_requests_per_rpc` | Measures the number of messages received per RPC. Should be 1 for all non-streaming RPCs. | Histogram | +| `rpc_client_response_size` | Measures the size of RPC response messages (uncompressed). | Histogram | +| `rpc_client_responses_per_rpc` | Measures the number of messages sent per RPC. Should be 1 for all non-streaming RPCs. | Histogram | +| `rpc_server_duration` | Measures the duration of inbound RPC. | Histogram | +| `rpc_server_request_size` | Measures the size of RPC request messages (uncompressed). | Histogram | +| `rpc_server_requests_per_rpc` | Measures the number of messages received per RPC. Should be 1 for all non-streaming RPCs. | Histogram | +| `rpc_server_response_size` | Measures the size of RPC response messages (uncompressed). | Histogram | +| `rpc_server_responses_per_rpc` | Measures the number of messages sent per RPC. Should be 1 for all non-streaming RPCs. | Histogram | + +### Events observable with internal logs + +The Collector logs the following internal events: + +- A Collector instance starts or stops. +- Data dropping begins due to throttling for a specified reason, such as local + saturation, downstream saturation, downstream unavailable, etc. +- Data dropping due to throttling stops. +- Data dropping begins due to invalid data. A sample of the invalid data is + included. +- Data dropping due to invalid data stops. +- A crash is detected, differentiated from a clean stop. Crash data is included + if available. diff --git a/content/en/docs/languages/go/getting-started.md b/content/en/docs/languages/go/getting-started.md index 768eb94403ad..4f7baea20e52 100644 --- a/content/en/docs/languages/go/getting-started.md +++ b/content/en/docs/languages/go/getting-started.md @@ -11,13 +11,20 @@ cSpell:ignore: chan fatalln funcs intn itoa khtml otelhttp rolldice stdouttrace This page will show you how to get started with OpenTelemetry in Go. You will learn how you can instrument a simple application manually, in such a -way that [traces][] and [metrics][] are emitted to the console. +way that [traces][], [metrics][], and [logs][] are emitted to the console. + +{{% alert title="Note" %}} + +The logs signal is still experimental. Breaking changes may be introduced in +future versions. + +{{% /alert %}} ## Prerequisites Ensure that you have the following installed locally: -- [Go](https://go.dev/) +- [Go](https://go.dev/) 1.22 or greater ## Example application @@ -103,12 +110,16 @@ Install the following packages: go get "go.opentelemetry.io/otel" \ "go.opentelemetry.io/otel/exporters/stdout/stdoutmetric" \ "go.opentelemetry.io/otel/exporters/stdout/stdouttrace" \ + "go.opentelemetry.io/otel/exporters/stdout/stdoutlog" \ + "go.opentelemetry.io/otel/sdk/log" \ + "go.opentelemetry.io/otel/log/global" \ "go.opentelemetry.io/otel/propagation" \ "go.opentelemetry.io/otel/sdk/metric" \ "go.opentelemetry.io/otel/sdk/resource" \ "go.opentelemetry.io/otel/sdk/trace" \ "go.opentelemetry.io/otel/semconv/v1.24.0" \ - "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" + "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"\ + "go.opentelemetry.io/contrib/bridges/otelslog" ``` This installs OpenTelemetry SDK components and `net/http` instrumentation. @@ -135,9 +146,12 @@ import ( "time" "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/exporters/stdout/stdoutlog" "go.opentelemetry.io/otel/exporters/stdout/stdoutmetric" "go.opentelemetry.io/otel/exporters/stdout/stdouttrace" + "go.opentelemetry.io/otel/log/global" "go.opentelemetry.io/otel/propagation" + "go.opentelemetry.io/otel/sdk/log" "go.opentelemetry.io/otel/sdk/metric" "go.opentelemetry.io/otel/sdk/trace" ) @@ -186,6 +200,15 @@ func setupOTelSDK(ctx context.Context) (shutdown func(context.Context) error, er shutdownFuncs = append(shutdownFuncs, meterProvider.Shutdown) otel.SetMeterProvider(meterProvider) + // Set up logger provider. + loggerProvider, err := newLoggerProvider() + if err != nil { + handleErr(err) + return + } + shutdownFuncs = append(shutdownFuncs, loggerProvider.Shutdown) + global.SetLoggerProvider(loggerProvider) + return } @@ -224,6 +247,18 @@ func newMeterProvider() (*metric.MeterProvider, error) { ) return meterProvider, nil } + +func newLoggerProvider() (*log.LoggerProvider, error) { + logExporter, err := stdoutlog.New() + if err != nil { + return nil, err + } + + loggerProvider := log.NewLoggerProvider( + log.WithProcessor(log.NewBatchProcessor(logExporter)), + ) + return loggerProvider, nil +} ``` @@ -318,7 +353,8 @@ func newHTTPHandler() http.Handler { } // Register handlers. - handleFunc("/rolldice", rolldice) + handleFunc("/rolldice/", rolldice) + handleFunc("/rolldice/{player}", rolldice) // Add HTTP instrumentation for the whole server. handler := otelhttp.NewHandler(mux, "/") @@ -348,14 +384,23 @@ import ( "net/http" "strconv" + "go.opentelemetry.io/contrib/bridges/otelslog" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/metric" + "go.opentelemetry.io/otel/sdk/instrumentation" ) +const name = "rolldice" + var ( - tracer = otel.Tracer("rolldice") - meter = otel.Meter("rolldice") + tracer = otel.Tracer(name) + meter = otel.Meter(name) + logger = otelslog.NewLogger( + otelslog.WithInstrumentationScope(instrumentation.Scope{ + Name: name, + }), + ) rollCnt metric.Int64Counter ) @@ -375,6 +420,14 @@ func rolldice(w http.ResponseWriter, r *http.Request) { roll := 1 + rand.Intn(6) + var msg string + if player := r.PathValue("player"); player != "" { + msg = fmt.Sprintf("%s is rolling the dice", player) + } else { + msg = "Anonymous player is rolling the dice" + } + logger.InfoContext(ctx, msg, "result", roll) + rollValueAttr := attribute.Int("roll.value", roll) span.SetAttributes(rollValueAttr) rollCnt.Add(ctx, 1, metric.WithAttributes(rollValueAttr)) @@ -400,11 +453,11 @@ export OTEL_RESOURCE_ATTRIBUTES="service.name=dice,service.version=0.1.0" go run . ``` -Open in your web browser. When you send a +Open in your web browser. When you send a request to the server, you'll see two spans in the trace emitted to the console. The span generated by the instrumentation library tracks the lifetime of a -request to the `/rolldice` route. The span called `roll` is created manually and -it is a child of the previously mentioned span. +request to the `/rolldice/{player}` route. The span called `roll` is created +manually and it is a child of the previously mentioned span.
View example output @@ -571,7 +624,7 @@ it is a child of the previously mentioned span. "Key": "http.route", "Value": { "Type": "STRING", - "Value": "/rolldice" + "Value": "/rolldice/Alice" } }, { @@ -646,8 +699,83 @@ it is a child of the previously mentioned span.
-Refresh the page a few times, and then either -wait for a little bit or terminate the app and you'll see metrics as in the +Along with the trace, log messages are emitted to the console. + +
+View example output + +```json +{ + "Timestamp": "2023-09-25T12:42:05.177136776+02:00", + "ObservedTimestamp": "2023-09-25T12:42:06.809396011+02:00", + "Severity": 9, + "SeverityText": "", + "Body": { + "Type": "String", + "Value": "Alice is rolling the dice" + }, + "Attributes": [ + { + "Key": "result", + "Value": { + "Type": "Int64", + "Value": 6 + } + } + ], + "TraceID": "829fb7ceb787403c96eac3caf285c965", + "SpanID": "8b6b408b6c1a35e5", + "TraceFlags": "01", + "Resource": [ + { + "Key": "service.name", + "Value": { + "Type": "STRING", + "Value": "dice" + } + }, + { + "Key": "service.version", + "Value": { + "Type": "STRING", + "Value": "0.1.0" + } + }, + { + "Key": "telemetry.sdk.language", + "Value": { + "Type": "STRING", + "Value": "go" + } + }, + { + "Key": "telemetry.sdk.name", + "Value": { + "Type": "STRING", + "Value": "opentelemetry" + } + }, + { + "Key": "telemetry.sdk.version", + "Value": { + "Type": "STRING", + "Value": "1.19.0-rc.1" + } + } + ], + "Scope": { + "Name": "rolldice", + "Version": "", + "SchemaURL": "" + }, + "DroppedAttributes": 0 +} +``` + +
+ +Refresh the page a few times, and then +either wait a little or terminate the app and you'll see metrics as in the console output. You'll see the `dice.rolls` metric emitted to the console, with separate counts for each roll value, as well as the HTTP metrics generated by the instrumentation library. @@ -832,7 +960,7 @@ the instrumentation library. "Key": "http.route", "Value": { "Type": "STRING", - "Value": "/rolldice" + "Value": "/rolldice/Alice" } }, { @@ -899,7 +1027,7 @@ the instrumentation library. "Key": "http.route", "Value": { "Type": "STRING", - "Value": "/rolldice" + "Value": "/rolldice/Alice" } }, { @@ -966,7 +1094,7 @@ the instrumentation library. "Key": "http.route", "Value": { "Type": "STRING", - "Value": "/rolldice" + "Value": "/rolldice/Alice" } }, { @@ -1041,3 +1169,4 @@ If you'd like to explore a more complex example, take a look at the [traces]: /docs/concepts/signals/traces/ [metrics]: /docs/concepts/signals/metrics/ +[logs]: /docs/concepts/signals/logs/ diff --git a/content/en/docs/languages/go/instrumentation.md b/content/en/docs/languages/go/instrumentation.md index 1b2e51471c36..aa5811b0b7be 100644 --- a/content/en/docs/languages/go/instrumentation.md +++ b/content/en/docs/languages/go/instrumentation.md @@ -5,7 +5,7 @@ aliases: - manual_instrumentation weight: 30 description: Manual instrumentation for OpenTelemetry Go -cSpell:ignore: fatalf otlptrace sdktrace sighup +cSpell:ignore: fatalf logr logrus otelslog otlplog otlploghttp sdktrace sighup --- {{% docs/languages/instrumentation-intro %}} @@ -37,7 +37,6 @@ import ( "log" "go.opentelemetry.io/otel" - "go.opentelemetry.io/otel/exporters/otlp/otlptrace" "go.opentelemetry.io/otel/sdk/resource" sdktrace "go.opentelemetry.io/otel/sdk/trace" semconv "go.opentelemetry.io/otel/semconv/v1.21.0" @@ -876,7 +875,161 @@ meterProvider := metric.NewMeterProvider( ## Logs -The logs API is currently unstable, documentation TBA. +Logs are distinct from metrics and traces in that **there is no user-facing +OpenTelemetry logs API**. Instead, there is tooling to bridge logs from existing +popular log packages (such as slog, logrus, zap, logr) into the OpenTelemetry +ecosystem. For rationale behind this design decision, see +[Logging specification](/docs/specs/otel/logs/). + +The two typical workflows discussed below each cater to different application +requirements. + +### Direct-to-Collector + +**Status**: [Experimental](/docs/specs/otel/document-status/) + +In the direct-to-Collector workflow, logs are emitted directly from an +application to a collector using a network protocol (e.g. OTLP). This workflow +is simple to set up as it doesn't require any additional log forwarding +components, and allows an application to easily emit structured logs that +conform to the [log data model][log data model]. However, the overhead required +for applications to queue and export logs to a network location may not be +suitable for all applications. + +To use this workflow: + +- Configure the OpenTelemetry [Log SDK](#logs-sdk) to export log records to + desired target destination (the [collector][opentelemetry collector] or + other). +- Use an appropriate [Log Bridge](#log-bridge). + +#### Logs SDK + +The logs SDK dictates how logs are processed when using the +[direct-to-Collector](#direct-to-collector) workflow. No log SDK is needed when +using the [log forwarding](#via-file-or-stdout) workflow. + +The typical log SDK configuration installs a batching log record processor with +an OTLP exporter. + +To enable [logs](/docs/concepts/signals/logs/) in your app, you'll need to have +an initialized [`LoggerProvider`](/docs/concepts/signals/logs/#logger-provider) +that will let you use a [Log Bridge](#log-bridge). + +If a `LoggerProvider` is not created, the OpenTelemetry APIs for logs will use a +no-op implementation and fail to generate data. Therefore, you have to modify +the source code to include the SDK initialization code using the following +packages: + +- [`go.opentelemetry.io/otel`][] +- [`go.opentelemetry.io/otel/sdk/log`][] +- [`go.opentelemetry.io/otel/sdk/resource`][] +- [`go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp`][] + +Ensure you have the right Go modules installed: + +```sh +go get go.opentelemetry.io/otel \ + go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp \ + go.opentelemetry.io/otel/sdk \ + go.opentelemetry.io/otel/sdk/log +``` + +Then initialize a logger provider: + +```go +package main + +import ( + "context" + "fmt" + + "go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp" + "go.opentelemetry.io/otel/log/global" + "go.opentelemetry.io/otel/sdk/log" + "go.opentelemetry.io/otel/sdk/resource" + semconv "go.opentelemetry.io/otel/semconv/v1.21.0" +) + +func main() { + ctx := context.Background() + + // Create resource. + res, err := newResource() + if err != nil { + panic(err) + } + + // Create a logger provider. + // You can pass this instance directly when creating bridges. + loggerProvider, err := newLoggerProvider(ctx, res) + if err != nil { + panic(err) + } + + // Handle shutdown properly so nothing leaks. + defer func() { + if err := loggerProvider.Shutdown(ctx); err != nil { + fmt.Println(err) + } + }() + + // Register as global logger provider so that it can be accessed global.LoggerProvider. + // Most log bridges use the global logger provider as default. + // If the global logger provider is not set then a no-op implementation + // is used, which fails to generate data. + global.SetLoggerProvider(loggerProvider) +} + +func newResource() (*resource.Resource, error) { + return resource.Merge(resource.Default(), + resource.NewWithAttributes(semconv.SchemaURL, + semconv.ServiceName("my-service"), + semconv.ServiceVersion("0.1.0"), + )) +} + +func newLoggerProvider(ctx context.Context, res *resource.Resource) (*log.LoggerProvider, error) { + exporter, err := otlploghttp.New(ctx) + if err != nil { + return nil, err + } + processor := log.NewBatchProcessor(exporter) + provider := log.NewLoggerProvider( + log.WithResource(res), + log.WithProcessor(processor), + ) + return provider, nil +} +``` + +Now that a `LoggerProvider` is configured, you can use it to set up a +[Log Bridge](#log-bridge). + +#### Log Bridge + +A log bridge is a component that bridges logs from an existing log package into +the OpenTelemetry [Log SDK](#logs-sdk) using the [Logs Bridge +API][logs bridge API]. Log bridges are available for various popular Go log +packages: + +- [logrus bridge][otellogrus] +- [slog bridge][otelslog] + +The links above contain full usage and installation documentation. + +### Via file or stdout + +In the file or stdout workflow, logs are written to files or standout output. +Another component (e.g. FluentBit) is responsible for reading / tailing the +logs, parsing them to more structured format, and forwarding them a target, such +as the collector. This workflow may be preferable in situations where +application requirements do not permit additional overhead from +[direct-to-Collector](#direct-to-collector). However, it requires that all log +fields required down stream are encoded into the logs, and that the component +reading the logs parse the data into the [log data model][log data model]. The +installation and configuration of log forwarding components is outside the scope +of this document. ## Next Steps @@ -887,11 +1040,21 @@ telemetry backends. [opentelemetry specification]: /docs/specs/otel/ [trace semantic conventions]: /docs/specs/semconv/general/trace/ [instrumentation library]: ../libraries/ +[opentelemetry collector]: + https://github.com/open-telemetry/opentelemetry-collector +[logs bridge API]: /docs/specs/otel/logs/bridge-api +[log data model]: /docs/specs/otel/logs/data-model +[otellogrus]: https://pkg.go.dev/go.opentelemetry.io/contrib/bridges/otellogrus +[otelslog]: https://pkg.go.dev/go.opentelemetry.io/contrib/bridges/otelslog [`go.opentelemetry.io/otel`]: https://pkg.go.dev/go.opentelemetry.io/otel [`go.opentelemetry.io/otel/exporters/stdout/stdoutmetric`]: https://pkg.go.dev/go.opentelemetry.io/otel/exporters/stdout/stdoutmetric [`go.opentelemetry.io/otel/metric`]: https://pkg.go.dev/go.opentelemetry.io/otel/metric +[`go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp`]: + https://pkg.go.dev/go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp +[`go.opentelemetry.io/otel/sdk/log`]: + https://pkg.go.dev/go.opentelemetry.io/otel/sdk/log [`go.opentelemetry.io/otel/sdk/metric`]: https://pkg.go.dev/go.opentelemetry.io/otel/sdk/metric [`go.opentelemetry.io/otel/sdk/resource`]: diff --git a/content/en/docs/languages/go/resources.md b/content/en/docs/languages/go/resources.md index 4acbfc275868..dea97339c231 100644 --- a/content/en/docs/languages/go/resources.md +++ b/content/en/docs/languages/go/resources.md @@ -6,8 +6,8 @@ cSpell:ignore: sdktrace thirdparty {{% docs/languages/resources-intro %}} -Resources should be assigned to a tracer provider at its initialization, and are -created much like attributes: +Resources should be assigned to a tracer, meter, and logger provider at its +initialization, and are created much like attributes: ```go res := resource.NewWithAttributes( diff --git a/content/en/docs/languages/java/_index.md b/content/en/docs/languages/java/_index.md index e93d9e45532c..eaf9e8357510 100644 --- a/content/en/docs/languages/java/_index.md +++ b/content/en/docs/languages/java/_index.md @@ -6,7 +6,7 @@ description: >- aliases: [/java, /java/metrics, /java/tracing] cascade: vers: - instrumentation: 2.3.0 + instrumentation: 2.4.0 otel: 1.38.0 semconv: 1.25.0 weight: 18 diff --git a/content/en/docs/languages/net/instrumentation.md b/content/en/docs/languages/net/instrumentation.md index bf8310bb189e..5cad2ffca78d 100644 --- a/content/en/docs/languages/net/instrumentation.md +++ b/content/en/docs/languages/net/instrumentation.md @@ -3,10 +3,24 @@ title: Instrumentation weight: 20 aliases: [manual] description: Instrumentation for OpenTelemetry .NET +cSpell:ignore: dicelib rolldice --- {{% docs/languages/instrumentation-intro %}} +{{% alert title="Note" color="info" %}} + +On this page you will learn how you can add traces, metrics and logs to your +code manually. You are not limited to using one kind of instrumentation: you can +also use [automatic instrumentation](/docs/languages/net/automatic/) to get +started and then enrich your code with manual instrumentation as needed. + +Also, for libraries your code depends on, you don't have to write +instrumentation code yourself, since they might be already instrumented or there +are [instrumentation libraries](/docs/languages/net/libraries/) for them. + +{{% /alert %}} + ## A note on terminology .NET is different from other languages/runtimes that support OpenTelemetry. The @@ -22,360 +36,641 @@ are covered here as well as the `System.Diagnostics` API. If you prefer to use OpenTelemetry APIs instead of `System.Diagnostics` APIs, you can refer to the [OpenTelemetry API Shim docs for tracing](../shim). -## Traces +## Example app preparation {#example-app} -### Initializing tracing +This page uses a modified version of the example app from +[Getting Started](/docs/languages/net/getting-started/) to help you learn about +manual instrumentation. -There are two main ways to initialize [tracing](/docs/concepts/signals/traces/), -depending on whether you're using a console app or something that's ASP.NET -Core-based. +You don't have to use the example app: if you want to instrument your own app or +library, follow the instructions here to adapt the process to your own code. -#### Console app +### Prerequisites {#example-app-prerequisites} -To start tracing in a console app, you need to create a tracer provider. +- [.NET SDK](https://dotnet.microsoft.com/download/dotnet) 6+ -First, ensure that you have the right packages: +### Create and launch an HTTP Server -```sh -dotnet add package OpenTelemetry -dotnet add package OpenTelemetry.Exporter.Console +To begin, set up an environment in a new directory called `dotnet-otel-example`. +Within that directory, execute following command: + +```shell +dotnet new web ``` -And then use code like this at the beginning of your program, during any -important startup operations. +To highlight the difference between instrumenting a library and a standalone +app, split out the dice rolling into a library file, which then will be imported +as a dependency by the app file. + +Create the library file named `Dice.cs` and add the following code to it: ```csharp -using OpenTelemetry; -using OpenTelemetry.Resources; -using OpenTelemetry.Trace; +/*Dice.cs*/ -// ... +public class Dice +{ + private int min; + private int max; -var serviceName = "MyServiceName"; -var serviceVersion = "1.0.0"; + public Dice(int min, int max) + { + this.min = min; + this.max = max; + } -using var tracerProvider = Sdk.CreateTracerProviderBuilder() - .AddSource(serviceName) - .ConfigureResource(resource => - resource.AddService( - serviceName: serviceName, - serviceVersion: serviceVersion)) - .AddConsoleExporter() - .Build(); + public List rollTheDice(int rolls) + { + List results = new List(); + + for (int i = 0; i < rolls; i++) + { + results.Add(rollOnce()); + } -// ... + return results; + } + + private int rollOnce() + { + return Random.Shared.Next(min, max + 1); + } +} ``` -This is also where you can configure instrumentation libraries. +Create the app file `DiceController.cs` and add the following code to it: + +```csharp +/*DiceController.cs*/ + +using Microsoft.AspNetCore.Mvc; +using System.Net; -Note that this sample uses the Console Exporter. If you are exporting to another -endpoint, you'll have to use a different exporter. -#### ASP.NET Core +public class DiceController : ControllerBase +{ + private ILogger logger; -To start tracing in an ASP.NET Core-based app, use the OpenTelemetry extensions -for ASP.NET Core setup. + public DiceController(ILogger logger) + { + this.logger = logger; + } -First, ensure that you have the right packages: + [HttpGet("/rolldice")] + public List RollDice(string player, int? rolls) + { + if(!rolls.HasValue) + { + logger.LogError("Missing rolls parameter"); + throw new HttpRequestException("Missing rolls parameter", null, HttpStatusCode.BadRequest); + } + + var result = new Dice(1, 6).rollTheDice(rolls.Value); + + if (string.IsNullOrEmpty(player)) + { + logger.LogInformation("Anonymous player is rolling the dice: {result}", result); + } + else + { + logger.LogInformation("{player} is rolling the dice: {result}", player, result); + } + + return result; + } +} +``` + +Replace the content of the Program.cs file with the following code: + +```csharp +var builder = WebApplication.CreateBuilder(args); + +builder.Services.AddControllers(); + +var app = builder.Build(); + +app.MapControllers(); + +app.Run(); +``` + +In the `Properties` subdirectory, replace the content of `launchSettings.json` +with the following: + +```json +{ + "$schema": "http://json.schemastore.org/launchsettings.json", + "profiles": { + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "http://localhost:8080", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} +``` + +To ensure that it is working, run the application with the following command and +open in your web browser: + +```sh +dotnet run +``` + +You should get a list of 12 numbers in your browser window, for example: + +```text +[5,6,5,3,6,1,2,5,4,4,2,4] +``` + +## Manual instrumentation setup + +### Dependencies + +Install the following OpenTelemetry NuGet packages: + +[OpenTelemetry.Exporter.Console](https://www.nuget.org/packages/OpenTelemetry.Exporter.Console) + +[OpenTelemetry.Extensions.Hosting](https://www.nuget.org/packages/OpenTelemetry.Extensions.Hosting) ```sh -dotnet add package OpenTelemetry -dotnet add package OpenTelemetry.Extensions.Hosting dotnet add package OpenTelemetry.Exporter.Console +dotnet add package OpenTelemetry.Extensions.Hosting ``` -Then you can install the Instrumentation package +For ASP.NET Core-based applications, also install the AspNetCore instrumentation +package + +[OpenTelemetry.Instrumentation.AspNetCore](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.AspNetCore) ```sh -dotnet add package OpenTelemetry.Instrumentation.AspNetCore --prerelease +dotnet add package OpenTelemetry.Instrumentation.AspNetCore ``` -Note that the `--prerelease` flag is required for all instrumentation packages -because they are all dependent on naming conventions for attributes/labels -(Semantic Conventions) that aren't yet classed as stable. +### Initialize the SDK + +{{% alert title="Note" color="info" %}} If you’re instrumenting a library, you +don't need to initialize the SDK. {{% /alert %}} + +It is important to configure an instance of the OpenTelemetry SDK as early as +possible in your application. -Next, configure it in your ASP.NET Core startup routine where you have access to -an `IServiceCollection`. +To initialize the OpenTelemetry SDK for an ASP.NET Core app like in the case of +the example app, update the content of the `Program.cs` file with the following +code: ```csharp -using OpenTelemetry; +using OpenTelemetry.Logs; +using OpenTelemetry.Metrics; using OpenTelemetry.Resources; using OpenTelemetry.Trace; -// Define some important constants and the activity source. -// These can come from a config file, constants file, etc. -var serviceName = "MyCompany.MyProduct.MyService"; +// Ideally, you will want this name to come from a config file, constants file, etc. +var serviceName = "dice-server"; var serviceVersion = "1.0.0"; var builder = WebApplication.CreateBuilder(args); -// Configure important OpenTelemetry settings, the console exporter builder.Services.AddOpenTelemetry() - .WithTracing(b => - { - b - .AddSource(serviceName) - .ConfigureResource(resource => - resource.AddService( - serviceName: serviceName, - serviceVersion: serviceVersion)) - .AddAspNetCoreInstrumentation() - .AddConsoleExporter(); - }); + .ConfigureResource(resource => resource.AddService( + serviceName: serviceName, + serviceVersion: serviceVersion)) + .WithTracing(tracing => tracing + .AddSource(serviceName) + .AddAspNetCoreInstrumentation() + .AddConsoleExporter()) + .WithMetrics(metrics => metrics + .AddMeter(serviceName) + .AddConsoleExporter()); + +builder.Logging.AddOpenTelemetry(options => options + .SetResourceBuilder(ResourceBuilder.CreateDefault().AddService( + serviceName: serviceName, + serviceVersion: serviceVersion)) + .AddConsoleExporter()); + +builder.Services.AddControllers(); + +var app = builder.Build(); + +app.MapControllers(); + +app.Run(); ``` -This is also where you can configure instrumentation libraries. +If initializing the OpenTelemetry SDK for a console app, add the following code +at the beginning of your program, during any important startup operations. -Note that this sample uses the Console Exporter. If you are exporting to another -endpoint, you'll have to use a different exporter. +```csharp +using OpenTelemetry.Logs; +using OpenTelemetry.Resources; +using OpenTelemetry.Trace; -### Setting up an ActivitySource +//... -Once tracing is initialized, you can configure an -[`ActivitySource`](/docs/concepts/signals/traces/#tracer), which will be how you -trace operations with [`Activity`](/docs/concepts/signals/traces/#spans) -elements. +var serviceName = "MyServiceName"; +var serviceVersion = "1.0.0"; -Typically, an `ActivitySource` is instantiated once per app/service that is -being instrumented, so it's a good idea to instantiate it once in a shared -location. It is also typically named the same as the Service Name. +var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddSource(serviceName) + .ConfigureResource(resource => + resource.AddService( + serviceName: serviceName, + serviceVersion: serviceVersion)) + .AddConsoleExporter() + .Build(); -```csharp -using System.Diagnostics; +var meterProvider = Sdk.CreateMeterProviderBuilder() + .AddMeter(serviceName) + .AddConsoleExporter() + .Build(); -public static class Telemetry +var loggerFactory = LoggerFactory.Create(builder => { - //... + builder.AddOpenTelemetry(logging => + { + logging.AddConsoleExporter(); + }); +}); - // Name it after the service name for your app. - // It can come from a config file, constants file, etc. - public static readonly ActivitySource MyActivitySource = new(TelemetryConstants.ServiceName); +//... - //... -} +tracerProvider.Dispose(); +meterProvider.Dispose(); +loggerFactory.Dispose(); ``` -You can instantiate several `ActivitySource`s if that suits your scenario, -although it is generally sufficient to just have one defined per service. +For debugging and local development purposes, the example exports telemetry to +the console. After you have finished setting up manual instrumentation, you need +to configure an appropriate exporter to +[export the app's telemetry data](/docs/languages/net/exporters/) to one or more +telemetry backends. -### Creating Activities +The example also sets up the mandatory SDK default attribute `service.name`, +which holds the logical name of the service, and the optional, but highly +encouraged, attribute `service.version`, which holds the version of the service +API or implementation. Alternative methods exist for setting up resource +attributes. For more information, see +[Resources](/docs/languages/net/resources/). -To create an [`Activity`](/docs/concepts/signals/traces/#spans), give it a name -and create it from your -[`ActivitySource`](/docs/concepts/signals/traces/#tracer). +To verify your code, build and run the app: -```csharp -using var myActivity = MyActivitySource.StartActivity("SayHello"); - -// do work that 'myActivity' will now track +```sh +dotnet build +dotnet run ``` -### Creating nested Activities - -If you have a distinct sub-operation you'd like to track as a part of another -one, you can create activities to represent the relationship. +## Traces -```csharp -public static void ParentOperation() -{ - using var parentActivity = MyActivitySource.StartActivity("ParentActivity"); +### Initialize Tracing - // Do some work tracked by parentActivity +{{% alert title="Note" color="info" %}} If you’re instrumenting a library, you +don't need to initialize a TraceProvider. {{% /alert %}} - ChildOperation(); +To enable [tracing](/docs/concepts/signals/traces/) in your app, you'll need to +have an initialized +[`TracerProvider`](/docs/concepts/signals/traces/#tracer-provider) that will let +you create a [`Tracer`](/docs/concepts/signals/traces/#tracer). - // Finish up work tracked by parentActivity again -} +If a `TracerProvider` is not created, the OpenTelemetry APIs for tracing will +use a no-op implementation and fail to generate data. -public static void ChildOperation() -{ - using var childActivity = MyActivitySource.StartActivity("ChildActivity"); +If you followed the instructions to [initialize the SDK](#initialize-the-sdk) +above, you have a `TracerProvider` setup for you already. You can continue with +[setting up an ActivitySource](#setting-up-an-activitysource). - // Track work in ChildOperation with childActivity -} -``` +### Setting up an ActivitySource -When you view spans in a trace visualization tool, `ChildActivity` will be -tracked as a nested operation under `ParentActivity`. +Anywhere in your application where you write manual tracing code should +configure an [`ActivitySource`](/docs/concepts/signals/traces/#tracer), which +will be how you trace operations with +[`Activity`](/docs/concepts/signals/traces/#spans) elements. -### Nested Activities in the same scope +It’s generally recommended to define `ActivitySource` once per app/service that +is been instrumented, but you can instantiate several `ActivitySource`s if that +suits your scenario. -You may wish to create a parent-child relationship in the same scope. Although -possible, this is generally not recommended because you need to be careful to -end any nested `Activity` when you expect it to end. +In the case of the example app, we will create a new file `Instrumentation.cs` +as a custom type to hold reference for the ActivitySource. ```csharp -public static void DoWork() -{ - using var parentActivity = MyActivitySource.StartActivity("ParentActivity"); +using System.Diagnostics; - // Do some work tracked by parentActivity +/// +/// It is recommended to use a custom type to hold references for ActivitySource. +/// This avoids possible type collisions with other components in the DI container. +/// +public class Instrumentation : IDisposable +{ + internal const string ActivitySourceName = "dice-server"; + internal const string ActivitySourceVersion = "1.0.0"; - using (var childActivity = MyActivitySource.StartActivity("ChildActivity")) + public Instrumentation() { - // Do some "child" work in the same function + this.ActivitySource = new ActivitySource(ActivitySourceName, ActivitySourceVersion); } - // Finish up work tracked by parentActivity again + public ActivitySource ActivitySource { get; } + + public void Dispose() + { + this.ActivitySource.Dispose(); + } } ``` -In the preceding example, `childActivity` is ended because the scope of the -`using` block is explicitly defined, rather than scoped to `DoWork` itself like -`parentActivity`. +Then we will update the `Program.cs` to add the Instrument object as a +dependency injection: + +```csharp +//... + +// Register the Instrumentation class as a singleton in the DI container. +builder.Services.AddSingleton(); + +builder.Services.AddControllers(); -### Creating independent Activities +var app = builder.Build(); -The previous examples showed how to create Activities that follow a nested -hierarchy. In some cases, you'll want to create independent Activities that are -siblings of the same root rather than being nested. +app.MapControllers(); + +app.Run(); +``` + +In the application file `DiceController.cs` we will reference that +activitySource instance and the same activitySource instance will also be passed +to the library file `Dice.cs` ```csharp -public static void DoWork() +/*DiceController.cs*/ + +using Microsoft.AspNetCore.Mvc; +using System.Diagnostics; +using System.Net; + +public class DiceController : ControllerBase { - using var parent = MyActivitySource.StartActivity("parent"); + private ILogger logger; + + private ActivitySource activitySource; - using (var child1 = DemoSource.StartActivity("child1")) + public DiceController(ILogger logger, Instrumentation instrumentation) { - // Do some work that 'child1' tracks + this.logger = logger; + this.activitySource = instrumentation.ActivitySource; } - using (var child2 = DemoSource.StartActivity("child2")) + [HttpGet("/rolldice")] + public List RollDice(string player, int? rolls) { - // Do some work that 'child2' tracks + List result = new List(); + + if (!rolls.HasValue) + { + logger.LogError("Missing rolls parameter"); + throw new HttpRequestException("Missing rolls parameter", null, HttpStatusCode.BadRequest); + } + + result = new Dice(1, 6, activitySource).rollTheDice(rolls.Value); + + if (string.IsNullOrEmpty(player)) + { + logger.LogInformation("Anonymous player is rolling the dice: {result}", result); + } + else + { + logger.LogInformation("{player} is rolling the dice: {result}", player, result); + } + + return result; } - - // 'child1' and 'child2' both share 'parent' as a parent, but are independent - // from one another } ``` -### Creating new root Activities +```csharp +/*Dice.cs*/ -If you wish to create a new root Activity, you'll need to "de-parent" from the -current activity. +using System.Diagnostics; -```csharp -public static void DoWork() +public class Dice { - var previous = Activity.Current; - Activity.Current = null; + public ActivitySource activitySource; + private int min; + private int max; - var newRoot = MyActivitySource.StartActivity("NewRoot"); + public Dice(int min, int max, ActivitySource activitySource) + { + this.min = min; + this.max = max; + this.activitySource = activitySource; + } - // Re-set the previous Current Activity so the trace isn't messed up - Activity.Current = previous; + //... } ``` -### Get the current Activity +### Create Activities -Sometimes it's helpful to access whatever the current `Activity` is at a point -in time so you can enrich it with more information. +Now that you have [activitySources](/docs/concepts/signals/traces/#tracer) +initialized, you can create [activities](/docs/concepts/signals/traces/#spans). + +The code below illustrates how to create an activity. ```csharp -var activity = Activity.Current; -// may be null if there is none -``` +public List rollTheDice(int rolls) +{ + List results = new List(); -Note that `using` is not used in the prior example. Doing so will end current -`Activity`, which is not likely to be desired. + // It is recommended to create activities, only when doing operations that are worth measuring independently. + // Too many activities makes it harder to visualize in tools like Jaeger. + using (var myActivity = activitySource.StartActivity("rollTheDice")) + { + for (int i = 0; i < rolls; i++) + { + results.Add(rollOnce()); + } -### Add tags to an Activity + return results; + } +} +``` -Tags (the equivalent of -[`Attributes`](/docs/concepts/signals/traces/#attributes) in OpenTelemetry) let -you attach key/value pairs to an `Activity` so it carries more information about -the current operation that it's tracking. +If you followed the instructions using the [example app](#example-app) up to +this point, you can copy the code above in your library file `Dice.cs`. You +should now be able to see activities/spans emitted from your app. -```csharp -using var myActivity = MyActivitySource.StartActivity("SayHello"); +Start your app as follows, and then send it requests by visiting + with your browser or curl. -activity?.SetTag("operation.value", 1); -activity?.SetTag("operation.name", "Saying hello!"); -activity?.SetTag("operation.other-stuff", new int[] { 1, 2, 3 }); +```sh +dotnet run ``` -We recommend that all Tag names are defined in constants rather than defined -inline as this provides both consistency and also discoverability. +After a while, you should see the spans printed in the console by the +`ConsoleExporter`, something like this: + +```json +Activity.TraceId: 841d70616c883db82b4ae4e11c728636 +Activity.SpanId: 9edfe4d69b0d6d8b +Activity.TraceFlags: Recorded +Activity.ParentSpanId: 39fcd105cf958377 +Activity.ActivitySourceName: dice-server +Activity.DisplayName: rollTheDice +Activity.Kind: Internal +Activity.StartTime: 2024-04-10T15:24:00.3620354Z +Activity.Duration: 00:00:00.0144329 +Resource associated with Activity: + service.name: dice-server + service.version: 1.0.0 + service.instance.id: 7a7a134f-3178-4ac6-9625-96df77cff8b4 + telemetry.sdk.name: opentelemetry + telemetry.sdk.language: dotnet + telemetry.sdk.version: 1.7.0 +``` -### Adding events +### Create nested Activities -An [event](/docs/concepts/signals/traces/#span-events) is a human-readable -message on an `Activity` that represents "something happening" during its -lifetime. +Nested [spans](/docs/concepts/signals/traces/#spans) let you track work that's +nested in nature. For example, the `rollOnce()` function below represents a +nested operation. The following sample creates a nested span that tracks +`rollOnce()`: ```csharp -using var myActivity = MyActivitySource.StartActivity("SayHello"); +private int rollOnce() +{ + using (var childActivity = activitySource.StartActivity("rollOnce")) + { + int result; -// ... + result = Random.Shared.Next(min, max + 1); -myActivity?.AddEvent(new("Gonna try it!")); + return result; + } +} +``` -// ... +When you view the spans in a trace visualization tool, `rollOnce` childActivity +will be tracked as a nested operation under `rollTheDice` activity. -myActivity?.AddEvent(new("Did it!")); +### Get the current Activity + +Sometimes it’s helpful to do something with the current/active Activity/Span at +a particular point in program execution. + +```csharp +var activity = Activity.Current; ``` -Events can also be created with a timestamp and a collection of Tags. +### Activity Tags + +Tags (the equivalent of [Attributes](/docs/concepts/signals/traces/#attributes)) +let you attach key/value pairs to an +[`Activity`](/docs/concepts/signals/traces/#spans) so it carries more +information about the current operation that it's tracking. ```csharp -using var myActivity = MyActivitySource.StartActivity("SayHello"); +private int rollOnce() +{ + using (var childActivity = activitySource.StartActivity("rollOnce")) + { + int result; + + result = Random.Shared.Next(min, max + 1); + childActivity?.SetTag("dicelib.rolled", result); -// ... + return result; + } +} +``` -myActivity?.AddEvent(new("Gonna try it!", DateTimeOffset.Now)); +### Add Events to Activities -// ... +[Spans](/docs/concepts/signals/traces/#spans) can be annotated with named events +(called [Span Events](/docs/concepts/signals/traces/#span-events)) that can +carry zero or more [Span Attributes](#activity-tags), each of which itself is a +key:value map paired automatically with a timestamp. -var eventTags = new Dictionary +```csharp +myActivity?.AddEvent(new("Init")); +... +myActivity?.AddEvent(new("End")); +``` + +```csharp +var eventTags = new ActivityTagsCollection { - { "foo", 1 }, - { "bar", "Hello, World!" }, - { "baz", new int[] { 1, 2, 3 } } + { "operation", "calculate-pi" }, + { "result", 3.14159 } }; -myActivity?.AddEvent(new("Gonna try it!", DateTimeOffset.Now, new(eventTags))); +activity?.AddEvent(new("End Computation", DateTimeOffset.Now, eventTags)); ``` -### Adding links +### Create Activities with links -An `Activity` can be created with zero or more -[`ActivityLink`s](/docs/concepts/signals/traces/#span-links) that are causally -related. +A [Span](/docs/concepts/signals/traces/#spans) may be linked to zero or more +other Spans that are causally related via a +[Span Link](/docs/concepts/signals/traces/#span-links). Links can be used to +represent batched operations where a Span was initiated by multiple initiating +Spans, each representing a single incoming item being processed in the batch. ```csharp -// Get a context from somewhere, perhaps it's passed in as a parameter -var activityContext = Activity.Current!.Context; - var links = new List { - new ActivityLink(activityContext) + new ActivityLink(activityContext1), + new ActivityLink(activityContext2), + new ActivityLink(activityContext3) }; -using var anotherActivity = - MyActivitySource.StartActivity( - ActivityKind.Internal, - name: "anotherActivity", - links: links); - -// do some work +var activity = MyActivitySource.StartActivity( + ActivityKind.Internal, + name: "activity-with-links", + links: links); ``` ### Set Activity status {{% docs/languages/span-status-preamble %}} -```csharp -using var myActivity = MyActivitySource.StartActivity("SayHello"); +A [status](/docs/concepts/signals/traces/#span-status) can be set on a +[span](/docs/concepts/signals/traces/#spans), typically used to specify that a +span has not completed successfully - `SpanStatus.Error`. -try -{ - // do something -} -catch (Exception ex) +By default, all spans are `Unset`, which means a span completed without error. +The `Ok` status is reserved for when you need to explicitly mark a span as +successful rather than stick with the default of Unset (i.e., “without error”). + +The status can be set at any time before the span is finished. + +It can be a good idea to record exceptions when they happen. It's recommended to +do this in conjunction with +[setting span status](/docs/specs/otel/trace/api/#set-status). + +```csharp +private int rollOnce() { - myActivity.SetStatus(ActivityStatusCode.Error, "Something bad happened!"); + using (var childActivity = activitySource.StartActivity("rollOnce")) + { + int result; + + try + { + result = Random.Shared.Next(min, max + 1); + childActivity?.SetTag("dicelib.rolled", result); + } + catch (Exception ex) + { + childActivity?.SetStatus(ActivityStatusCode.Error, "Something bad happened!"); + childActivity?.RecordException(ex); + throw; + } + + return result; + } } ``` diff --git a/content/en/docs/languages/net/netframework.md b/content/en/docs/languages/net/netframework.md index 1b8a590cc695..29c90a7b3d3f 100644 --- a/content/en/docs/languages/net/netframework.md +++ b/content/en/docs/languages/net/netframework.md @@ -131,8 +131,8 @@ this.tracerProvider = Sdk.CreateTracerProviderBuilder() .Build(); ``` -See [Add tags to an Activity](../instrumentation/#add-tags-to-an-activity) for -annotating trace data more generally. +See [Add tags to an Activity](../instrumentation/#activity-tags) for annotating +trace data more generally. ### RecordException diff --git a/content/en/docs/languages/python/getting-started.md b/content/en/docs/languages/python/getting-started.md index c517018138d5..53ac6c716ad4 100644 --- a/content/en/docs/languages/python/getting-started.md +++ b/content/en/docs/languages/python/getting-started.md @@ -418,7 +418,7 @@ automatically created one: -The `parent_id` of `roll` is the same is the `span_id` for `/rolldice`, +The `parent_id` of `roll` is the same as the `span_id` for `/rolldice`, indicating a parent-child relationship! ### Metrics diff --git a/data/registry/exporter-dotnet-azure.yml b/data/registry/exporter-dotnet-azure.yml index b733e00c7750..46d2b2e83d27 100644 --- a/data/registry/exporter-dotnet-azure.yml +++ b/data/registry/exporter-dotnet-azure.yml @@ -13,7 +13,7 @@ authors: package: name: Azure.Monitor.OpenTelemetry.Exporter registry: nuget - version: 1.3.0-beta.1 + version: 1.3.0-beta.2 urls: repo: https://github.com/Azure/azure-sdk-for-net/tree/main/sdk/monitor/Azure.Monitor.OpenTelemetry.Exporter createdAt: 2021-11-01 diff --git a/data/registry/exporter-dotnet-geneva.yml b/data/registry/exporter-dotnet-geneva.yml index 103cb8988287..8d9644ba30b5 100644 --- a/data/registry/exporter-dotnet-geneva.yml +++ b/data/registry/exporter-dotnet-geneva.yml @@ -17,4 +17,4 @@ createdAt: 2022-11-07 package: registry: nuget name: OpenTelemetry.Exporter.Geneva - version: 1.8.0-rc.2 + version: 1.8.0 diff --git a/data/registry/exporter-js-instana.yml b/data/registry/exporter-js-instana.yml index dc718218421f..b7073138f8a6 100644 --- a/data/registry/exporter-js-instana.yml +++ b/data/registry/exporter-js-instana.yml @@ -15,4 +15,4 @@ createdAt: 2022-04-18 package: registry: npm name: '@instana/opentelemetry-exporter' - version: 3.8.0 + version: 3.8.1 diff --git a/data/registry/instrumentation-js-aws-lambda.yml b/data/registry/instrumentation-js-aws-lambda.yml index cd3b11a05621..45c25c108d4b 100644 --- a/data/registry/instrumentation-js-aws-lambda.yml +++ b/data/registry/instrumentation-js-aws-lambda.yml @@ -15,4 +15,4 @@ createdAt: 2021-07-08 package: name: '@opentelemetry/instrumentation-aws-lambda' registry: npm - version: 0.41.0 + version: 0.41.1 diff --git a/data/registry/instrumentation-js-cerbos.yml b/data/registry/instrumentation-js-cerbos.yml index 2633948f75c6..c16a310b167a 100644 --- a/data/registry/instrumentation-js-cerbos.yml +++ b/data/registry/instrumentation-js-cerbos.yml @@ -18,5 +18,5 @@ createdAt: 2023-09-13 package: name: '@cerbos/opentelemetry' registry: npm - version: 0.4.6 + version: 0.5.0 isFirstParty: true diff --git a/data/registry/instrumentation-js-connect.yml b/data/registry/instrumentation-js-connect.yml index 03fdb79a4142..f739852bcb83 100644 --- a/data/registry/instrumentation-js-connect.yml +++ b/data/registry/instrumentation-js-connect.yml @@ -14,4 +14,4 @@ createdAt: 2020-11-09 package: name: '@opentelemetry/instrumentation-connect' registry: npm - version: 0.36.0 + version: 0.36.1 diff --git a/data/registry/instrumentation-js-express.yml b/data/registry/instrumentation-js-express.yml index e67b32dcfc9e..cc823e2eb482 100644 --- a/data/registry/instrumentation-js-express.yml +++ b/data/registry/instrumentation-js-express.yml @@ -14,4 +14,4 @@ createdAt: 2020-11-09 package: registry: npm name: '@opentelemetry/instrumentation-express' - version: 0.38.0 + version: 0.39.0 diff --git a/data/registry/instrumentation-php-psr16.yml b/data/registry/instrumentation-php-psr16.yml index 6e83ebf8c7d4..4bd8d95288d2 100644 --- a/data/registry/instrumentation-php-psr16.yml +++ b/data/registry/instrumentation-php-psr16.yml @@ -17,4 +17,4 @@ createdAt: 2024-04-18 package: registry: packagist name: open-telemetry/opentelemetry-auto-psr16 - version: 0.0.1 + version: 0.0.2 diff --git a/data/registry/instrumentation-php-slim.yml b/data/registry/instrumentation-php-slim.yml index bf2eb88bfabe..68369f8c4257 100644 --- a/data/registry/instrumentation-php-slim.yml +++ b/data/registry/instrumentation-php-slim.yml @@ -15,4 +15,4 @@ createdAt: 2022-12-14 package: registry: packagist name: open-telemetry/opentelemetry-auto-slim - version: 1.0.5 + version: 1.0.6 diff --git a/data/registry/resource-detector-js-aws.yml b/data/registry/resource-detector-js-aws.yml index c49560d096fc..dc13d5783647 100644 --- a/data/registry/resource-detector-js-aws.yml +++ b/data/registry/resource-detector-js-aws.yml @@ -15,4 +15,4 @@ createdAt: 2022-12-07 package: registry: npm name: '@opentelemetry/resource-detector-aws' - version: 1.4.2 + version: 1.5.0 diff --git a/hugo.yaml b/hugo.yaml index b09c98601110..8e8111939383 100644 --- a/hugo.yaml +++ b/hugo.yaml @@ -196,13 +196,6 @@ params: If you are interested in helping out, get in touch with the [Client Instrumentation SIG](https://docs.google.com/document/d/16Vsdh-DM72AfMg_FIt9yT9ExEWF4A_vRbQ3jRNBe09w). -services: - googleAnalytics: - # The following is a placeholder (fake) ID useful for local test builds. The - # real ID is set in the Netlify config. For details, see - # https://github.com/open-telemetry/opentelemetry.io/issues/1626. - id: UA-00000000-0 # TODO: switch to G-0000000000 once we get confirmation that it's ok to do so - security: funcs: # cspell:disable-line getenv: # cspell:disable-line diff --git a/layouts/partials/banner.md b/layouts/partials/banner.md index 8c913c87c6f4..11439c7851dc 100644 --- a/layouts/partials/banner.md +++ b/layouts/partials/banner.md @@ -1,17 +1,20 @@ -{{/* cSpell:ignore contribfest */ -}} -{{ if .Params.show_banner -}} - +{{/* cSpell:ignore markdownify */ -}} +{{ if and .Params.show_banner (gt (len (.Params.banners | default slice)) 0) }} + {{ $limit := .Params.limit_banner | default 2 }} + {{ $sorted := sort .Params.banners "to" }} + {{ $currentDate := now.Format "2006-01-02" }} + {{ $filtered := slice }} + {{ range $sorted }} + {{ if le $currentDate .to }} + {{ if lt (len $filtered) $limit }} + {{ $filtered = $filtered | append . }} + {{ end }} + {{ end }} + {{ end }}
- - Join us for -[**OTel Community Day** on June 25th](https://sessionize.com/OTel-Community-Day/)! - - + {{ range $filtered }} - -Help improve OTel and Prometheus interoperability: [complete our survey](https://forms.gle/bZAG9f7udoJsjZUG9) by May 31 -{.pt-0} - - +{{ .message | markdownify }} + {{ end }}
-{{ end -}} +{{ end -}} \ No newline at end of file diff --git a/layouts/partials/hooks/head-end.html b/layouts/partials/hooks/head-end.html index 9b65af633442..df4552a026f3 100644 --- a/layouts/partials/hooks/head-end.html +++ b/layouts/partials/hooks/head-end.html @@ -6,6 +6,22 @@ {{ $canonicalURL := .Permalink -}} + {{ $defaultLang := "en" -}} + {{ if and (ne .Language.Lang $defaultLang) .File -}} + {{/* This page is in a non-default-language section */ -}} + {{ $pagePath := strings.TrimPrefix (add hugo.WorkingDir "/content/") .File.Filename -}} + {{ if hasPrefix $pagePath $defaultLang -}} + + {{/* This page is actually a default-language fallback page. Use the link + to the origin of the fallback page as canonical reference. */ -}} + + {{ $translationPages := where .Translations "Lang" $defaultLang -}} + {{ $translation := index $translationPages 0 -}} + {{ with $translation -}} + {{ $canonicalURL = .Permalink -}} + {{ end -}} + {{ end -}} + {{ end -}} {{- end -}} diff --git a/package.json b/package.json index 5d5bf845d2b0..7baaadc62599 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ ], "scripts": { "__check:links": "make --keep-going check-links", - "_build": "hugo --cleanDestinationDir -e dev -DFE --baseURL \"${DEPLOY_PRIME_URL:-http://localhost}\"", + "_build": "npm run _hugo -- -e dev -DFE --baseURL \"${DEPLOY_PRIME_URL:-http://localhost}\"", "_check:format:any": "npx prettier --check --ignore-path ''", "_check:format": "npx prettier --check .", "_check:links--md": "npx markdown-link-check --config .markdown-link-check.json *.md", @@ -20,6 +20,7 @@ "_get:no": "echo SKIPPING get operation", "_get:submodule:non-lang": "npm run _get:submodule -- content-modules/opentelemetry-specification themes/docsy", "_get:submodule": "set -x && git submodule update --init ${DEPTH:- --depth 1}", + "_hugo": "hugo --cleanDestinationDir", "_list:check:*": "npm run --loglevel=warn | grep -Ee '^\\s*check:[^:]+$'", "_list:fix:*": "npm run --loglevel=warn | grep -Ee '^\\s*fix:[^:]+$' | grep -v 'fix:all'", "_ls-bad-filenames": "find assets content static -name '*_*' ! -name '_*'", @@ -32,7 +33,7 @@ "_sync": "./scripts/sync-submodules.pl", "all": "bash -c 'x=0; for c in \"$@\"; do npm run $c || x=$((x+1)); done; ((!x)) || (echo \"ERROR: some scripts failed!\" && exit 1)' -", "build:preview": "set -x && npm run _build -- --minify", - "build:production": "hugo --cleanDestinationDir --minify", + "build:production": "npm run _hugo -- --minify", "build": "npm run _build", "cd:public": "cd public &&", "check:filenames": "test -z \"$(npm run -s _ls-bad-filenames)\" || npm run -s _filename-error", diff --git a/static/refcache.json b/static/refcache.json index 60c272e12fa3..71f0a2d6bc83 100644 --- a/static/refcache.json +++ b/static/refcache.json @@ -4223,6 +4223,10 @@ "StatusCode": 200, "LastSeen": "2024-01-30T16:14:42.076218-05:00" }, + "https://github.com/open-telemetry/sig-end-user": { + "StatusCode": 200, + "LastSeen": "2024-05-13T17:48:19.136757+01:00" + }, "https://github.com/open-telemetry/sig-security": { "StatusCode": 200, "LastSeen": "2024-01-30T16:14:36.015951-05:00" @@ -7007,6 +7011,14 @@ "StatusCode": 200, "LastSeen": "2024-03-01T16:49:37.76693+01:00" }, + "https://pkg.go.dev/go.opentelemetry.io/contrib/bridges/otellogrus": { + "StatusCode": 200, + "LastSeen": "2024-05-15T16:22:37.734630943Z" + }, + "https://pkg.go.dev/go.opentelemetry.io/contrib/bridges/otelslog": { + "StatusCode": 200, + "LastSeen": "2024-05-10T11:02:15.508410781Z" + }, "https://pkg.go.dev/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp": { "StatusCode": 200, "LastSeen": "2024-01-19T15:36:28.468246594Z" @@ -7071,6 +7083,10 @@ "StatusCode": 200, "LastSeen": "2024-01-30T15:25:42.951557-05:00" }, + "https://pkg.go.dev/go.opentelemetry.io/otel/sdk/log": { + "StatusCode": 200, + "LastSeen": "2024-05-10T11:02:08.878761042Z" + }, "https://pkg.go.dev/go.opentelemetry.io/otel/sdk/metric": { "StatusCode": 200, "LastSeen": "2024-01-30T15:25:12.503352-05:00" diff --git a/themes/docsy b/themes/docsy index 6f7e81d34ca7..102892d931ab 160000 --- a/themes/docsy +++ b/themes/docsy @@ -1 +1 @@ -Subproject commit 6f7e81d34ca7c75558c5bc969969c96202a059ea +Subproject commit 102892d931ab79b573cb6aeca094b6f0f37b73b1