2020-11-19 22:41:09 +02:00
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
2021-01-29 22:26:49 +02:00
package main
2020-11-19 22:41:09 +02:00
import (
"context"
2021-06-16 17:32:42 +02:00
"fmt"
2020-11-19 22:41:09 +02:00
"log"
2021-03-11 19:49:20 +02:00
"time"
2020-11-19 22:41:09 +02:00
2021-03-11 19:49:20 +02:00
"go.opencensus.io/metric"
2021-11-13 18:35:04 +02:00
"go.opencensus.io/metric/metricdata"
2021-03-11 19:49:20 +02:00
"go.opencensus.io/metric/metricexport"
"go.opencensus.io/metric/metricproducer"
"go.opencensus.io/stats"
"go.opencensus.io/stats/view"
"go.opencensus.io/tag"
2020-11-19 22:41:09 +02:00
octrace "go.opencensus.io/trace"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/bridge/opencensus"
2021-06-16 17:32:42 +02:00
"go.opentelemetry.io/otel/exporters/stdout/stdoutmetric"
"go.opentelemetry.io/otel/exporters/stdout/stdouttrace"
2021-12-13 22:13:03 +02:00
"go.opentelemetry.io/otel/sdk/metric/export"
2020-11-19 22:41:09 +02:00
sdktrace "go.opentelemetry.io/otel/sdk/trace"
)
2021-03-11 19:49:20 +02:00
var (
// instrumenttype differentiates between our gauge and view metrics.
keyType = tag . MustNewKey ( "instrumenttype" )
2022-04-25 22:22:49 +02:00
// Counts the number of lines read in from standard input.
2021-03-11 19:49:20 +02:00
countMeasure = stats . Int64 ( "test_count" , "A count of something" , stats . UnitDimensionless )
countView = & view . View {
Name : "test_count" ,
Measure : countMeasure ,
Description : "A count of something" ,
Aggregation : view . Count ( ) ,
TagKeys : [ ] tag . Key { keyType } ,
}
)
2020-11-19 22:41:09 +02:00
func main ( ) {
2021-06-16 17:32:42 +02:00
log . Println ( "Using OpenTelemetry stdout exporters." )
traceExporter , err := stdouttrace . New ( stdouttrace . WithPrettyPrint ( ) )
2021-03-11 19:49:20 +02:00
if err != nil {
2021-06-16 17:32:42 +02:00
log . Fatal ( fmt . Errorf ( "error creating trace exporter: %w" , err ) )
2021-03-11 19:49:20 +02:00
}
2021-06-16 17:32:42 +02:00
metricsExporter , err := stdoutmetric . New ( stdoutmetric . WithPrettyPrint ( ) )
if err != nil {
log . Fatal ( fmt . Errorf ( "error creating metric exporter: %w" , err ) )
}
tracing ( traceExporter )
2022-05-19 22:15:07 +02:00
if err := monitoring ( metricsExporter ) ; err != nil {
log . Fatal ( err )
}
2021-03-11 19:49:20 +02:00
}
// tracing demonstrates overriding the OpenCensus DefaultTracer to send spans
// to the OpenTelemetry exporter by calling OpenCensus APIs.
2021-04-07 17:03:43 +02:00
func tracing ( otExporter sdktrace . SpanExporter ) {
2020-11-19 22:41:09 +02:00
ctx := context . Background ( )
log . Println ( "Configuring OpenCensus. Not Registering any OpenCensus exporters." )
octrace . ApplyConfig ( octrace . Config { DefaultSampler : octrace . AlwaysSample ( ) } )
2021-06-16 17:38:04 +02:00
tp := sdktrace . NewTracerProvider ( sdktrace . WithBatcher ( otExporter ) )
2020-11-19 22:41:09 +02:00
otel . SetTracerProvider ( tp )
log . Println ( "Installing the OpenCensus bridge to make OpenCensus libraries write spans using OpenTelemetry." )
tracer := tp . Tracer ( "simple" )
octrace . DefaultTracer = opencensus . NewTracer ( tracer )
2021-06-16 17:38:04 +02:00
tp . ForceFlush ( ctx )
2020-11-19 22:41:09 +02:00
2021-06-16 17:32:42 +02:00
log . Println ( "Creating OpenCensus span, which should be printed out using the OpenTelemetry stdouttrace exporter.\n-- It should have no parent, since it is the first span." )
2020-11-19 22:41:09 +02:00
ctx , outerOCSpan := octrace . StartSpan ( ctx , "OpenCensusOuterSpan" )
outerOCSpan . End ( )
2021-06-16 17:38:04 +02:00
tp . ForceFlush ( ctx )
2020-11-19 22:41:09 +02:00
log . Println ( "Creating OpenTelemetry span\n-- It should have the OpenCensus span as a parent, since the OpenCensus span was written with using OpenTelemetry APIs." )
ctx , otspan := tracer . Start ( ctx , "OpenTelemetrySpan" )
otspan . End ( )
2021-06-16 17:38:04 +02:00
tp . ForceFlush ( ctx )
2020-11-19 22:41:09 +02:00
2021-06-16 17:32:42 +02:00
log . Println ( "Creating OpenCensus span, which should be printed out using the OpenTelemetry stdouttrace exporter.\n-- It should have the OpenTelemetry span as a parent, since it was written using OpenTelemetry APIs" )
2020-11-19 22:41:09 +02:00
_ , innerOCSpan := octrace . StartSpan ( ctx , "OpenCensusInnerSpan" )
innerOCSpan . End ( )
2021-06-16 17:38:04 +02:00
tp . ForceFlush ( ctx )
2020-11-19 22:41:09 +02:00
}
2021-03-11 19:49:20 +02:00
// monitoring demonstrates creating an IntervalReader using the OpenTelemetry
// exporter to send metrics to the exporter by using either an OpenCensus
// registry or an OpenCensus view.
2022-05-19 22:15:07 +02:00
func monitoring ( otExporter export . Exporter ) error {
2021-06-16 17:32:42 +02:00
log . Println ( "Using the OpenTelemetry stdoutmetric exporter to export OpenCensus metrics. This allows routing telemetry from both OpenTelemetry and OpenCensus to a single exporter." )
2021-03-11 19:49:20 +02:00
ocExporter := opencensus . NewMetricExporter ( otExporter )
intervalReader , err := metricexport . NewIntervalReader ( & metricexport . Reader { } , ocExporter )
if err != nil {
2022-05-19 22:15:07 +02:00
return fmt . Errorf ( "failed to create interval reader: %w" , err )
2021-03-11 19:49:20 +02:00
}
intervalReader . ReportingInterval = 10 * time . Second
2021-06-16 17:32:42 +02:00
log . Println ( "Emitting metrics using OpenCensus APIs. These should be printed out using the OpenTelemetry stdoutmetric exporter." )
2021-03-11 19:49:20 +02:00
err = intervalReader . Start ( )
if err != nil {
2022-05-19 22:15:07 +02:00
return fmt . Errorf ( "failed to start interval reader: %w" , err )
2021-03-11 19:49:20 +02:00
}
defer intervalReader . Stop ( )
log . Println ( "Registering a gauge metric using an OpenCensus registry." )
r := metric . NewRegistry ( )
metricproducer . GlobalManager ( ) . AddProducer ( r )
gauge , err := r . AddInt64Gauge (
"test_gauge" ,
metric . WithDescription ( "A gauge for testing" ) ,
metric . WithConstLabel ( map [ metricdata . LabelKey ] metricdata . LabelValue {
{ Key : keyType . Name ( ) } : metricdata . NewLabelValue ( "gauge" ) ,
} ) ,
)
if err != nil {
2022-05-19 22:15:07 +02:00
return fmt . Errorf ( "failed to add gauge: %w" , err )
2021-03-11 19:49:20 +02:00
}
entry , err := gauge . GetEntry ( )
if err != nil {
2022-05-19 22:15:07 +02:00
return fmt . Errorf ( "failed to get gauge entry: %w" , err )
2021-03-11 19:49:20 +02:00
}
log . Println ( "Registering a cumulative metric using an OpenCensus view." )
if err := view . Register ( countView ) ; err != nil {
2022-05-19 22:15:07 +02:00
return fmt . Errorf ( "failed to register views: %w" , err )
2021-03-11 19:49:20 +02:00
}
ctx , err := tag . New ( context . Background ( ) , tag . Insert ( keyType , "view" ) )
if err != nil {
2022-05-19 22:15:07 +02:00
return fmt . Errorf ( "failed to set tag: %w" , err )
2021-03-11 19:49:20 +02:00
}
for i := int64 ( 1 ) ; true ; i ++ {
// update stats for our gauge
entry . Set ( i )
// update stats for our view
stats . Record ( ctx , countMeasure . M ( 1 ) )
time . Sleep ( time . Second )
}
2022-05-19 22:15:07 +02:00
return nil
2021-03-11 19:49:20 +02:00
}