mirror of
https://github.com/open-telemetry/opentelemetry-go.git
synced 2025-01-30 04:40:41 +02:00
Merge otlp collector examples (#841)
* Add metric instrumentation to example * Add prometheus configs * Add prometheus kubernetes configs * Correct Prometheus config files * Tweak prometheus configs * Change instrument to Counter * Elaborate example README * Polish submission * Correct otel config * Tweak details * Update licensing text * Modify licensing text * Fix typos Co-authored-by: Tyler Yahn <MrAlias@users.noreply.github.com> Co-authored-by: Tyler Yahn <MrAlias@users.noreply.github.com>
This commit is contained in:
parent
0e2fdfc682
commit
526b815f47
1
.gitignore
vendored
1
.gitignore
vendored
@ -15,7 +15,6 @@ coverage.*
|
||||
/example/http/server/server
|
||||
/example/jaeger/jaeger
|
||||
/example/namedtracer/namedtracer
|
||||
/example/otlp/otel-test
|
||||
/example/prometheus/prometheus
|
||||
/example/zipkin/zipkin
|
||||
/example/otel-collector/otel-collector
|
||||
|
@ -16,17 +16,24 @@ jaeger-operator-k8s:
|
||||
jaeger-k8s:
|
||||
kubectl apply -f k8s/jaeger.yaml
|
||||
|
||||
prometheus-k8s:
|
||||
kubectl apply -f k8s/prometheus-service.yaml # Prometheus instance
|
||||
kubectl apply -f k8s/prometheus-monitor.yaml # Service monitor
|
||||
|
||||
otel-collector-k8s:
|
||||
kubectl apply -f k8s/otel-collector.yaml
|
||||
|
||||
clean-k8s:
|
||||
- kubectl delete -f k8s/otel-collector.yaml
|
||||
|
||||
- kubectl delete -f k8s/prometheus-monitor.yaml
|
||||
- kubectl delete -f k8s/prometheus-service.yaml
|
||||
|
||||
- kubectl delete -f k8s/jaeger.yaml
|
||||
|
||||
- kubectl delete -f https://raw.githubusercontent.com/jaegertracing/jaeger-operator/master/deploy/cluster_role.yaml
|
||||
- kubectl delete -f https://raw.githubusercontent.com/jaegertracing/jaeger-operator/master/deploy/cluster_role_binding.yaml
|
||||
|
||||
|
||||
- kubectl delete -n observability -f https://raw.githubusercontent.com/jaegertracing/jaeger-operator/master/deploy/crds/jaegertracing.io_jaegers_crd.yaml
|
||||
- kubectl delete -n observability -f https://raw.githubusercontent.com/jaegertracing/jaeger-operator/master/deploy/service_account.yaml
|
||||
- kubectl delete -n observability -f https://raw.githubusercontent.com/jaegertracing/jaeger-operator/master/deploy/role.yaml
|
||||
|
@ -1,25 +1,70 @@
|
||||
# OpenTelemetry Collector Traces Example
|
||||
|
||||
This example illustrates how to export traces from the OpenTelemetry-Go SDK to the OpenTelemetry Collector, and from there to a Jaeger instance.
|
||||
This example illustrates how to export trace and metric data from the
|
||||
OpenTelemetry-Go SDK to the OpenTelemetry Collector. From there, we bring the
|
||||
trace data to Jaeger and the metric data to Prometheus
|
||||
The complete flow is:
|
||||
|
||||
`Demo App -> OpenTelemetry Collector -> Jaeger`
|
||||
```
|
||||
-----> Jaeger (trace)
|
||||
App + SDK ---> OpenTelemtry Collector ---|
|
||||
-----> Prometheus (metrics)
|
||||
```
|
||||
|
||||
# Prerequisites
|
||||
You will need access to a Kubernetes cluster for this demo. We use a local
|
||||
instance of [microk8s](https://microk8s.io/), but please feel free to pick
|
||||
your favorite. If you do decide to use microk8s, please ensure that dns
|
||||
and storage addons are enabled
|
||||
|
||||
The demo is built on Kubernetes, and uses a local instance of [microk8s](https://microk8s.io/). You will need access to a cluster in order to deploy the OpenTelemetry Collector and Jaeger components from this demo.
|
||||
```bash
|
||||
microk8s enable dns storage
|
||||
```
|
||||
|
||||
For simplicity, the demo application is not part of the k8s cluster, and will access the OpenTelemetry Collector through a NodePort on the cluster. Note that the NodePort opened by this demo is not secured.
|
||||
For simplicity, the demo application is not part of the k8s cluster, and will
|
||||
access the OpenTelemetry Collector through a NodePort on the cluster. Note that
|
||||
the NodePort opened by this demo is not secured.
|
||||
|
||||
Ideally you'd want to either have your application running as part of the kubernetes cluster, or use a secured connection (NodePort/LoadBalancer with TLS or an ingress extension).
|
||||
Ideally you'd want to either have your application running as part of the
|
||||
kubernetes cluster, or use a secured connection (NodePort/LoadBalancer with TLS
|
||||
or an ingress extension).
|
||||
|
||||
# Deploying Jaeger and OpenTelemetry Collector
|
||||
The first step of this demo is to deploy a Jaeger instance and a Collector to your cluster. All the necessary Kubernetes deployment files are available in this demo, in the [k8s](./k8s) folder.
|
||||
There are two ways to create the necessary deployments for this demo: using the [makefile](./Makefile) or manually applying the k8s files.
|
||||
# Deploying to Kubernetes
|
||||
All the necessary Kubernetes deployment files are available in this demo, in the
|
||||
[k8s](./k8s) folder. For your convenience, we assembled a [makefile](./Makefile)
|
||||
with deployment commands (see below). For those with subtly different systems,
|
||||
you are, of course, welcome to poke inside the Makefile and run the commands
|
||||
manually. If you use microk8s and alias `microk8s kubectl` to `kubectl`, the
|
||||
Makefile will not recognize the alias, and so the commands will have to be run
|
||||
manually.
|
||||
|
||||
## Setting up the Prometheus operator
|
||||
If you're using microk8s like us, simply do
|
||||
```bash
|
||||
microk8s enable prometheus
|
||||
```
|
||||
and you're good to go. Move on to [Using the makefile](#using-the-makefile).
|
||||
|
||||
Otherwise, obtain a copy of the Prometheus Operator stack from
|
||||
[coreos](https://github.com/coreos/kube-prometheus):
|
||||
```bash
|
||||
git clone https://github.com/coreos/kube-prometheus.git
|
||||
cd kube-prometheus
|
||||
kubectl create -f manifests/setup
|
||||
|
||||
# wait for namespaces and CRDs to become available, then
|
||||
kubectl create -f manifests/
|
||||
```
|
||||
|
||||
And to tear down the stack when you're finished:
|
||||
```bash
|
||||
kubectl delete --ignore-not-found=true -f manifests/ -f manifests/setup
|
||||
```
|
||||
|
||||
## Using the makefile
|
||||
Next, we can deploy our Jaeger instance, Prometheus monitor, and Collector
|
||||
using the [makefile](./Makefile).
|
||||
|
||||
For using the [makefile](./Makefile), run the following commands in order:
|
||||
```bash
|
||||
# Create the namespace
|
||||
make namespace-k8s
|
||||
@ -30,55 +75,36 @@ make jaeger-operator-k8s
|
||||
# After the operator is deployed, create the Jaeger instance
|
||||
make jaeger-k8s
|
||||
|
||||
# Then the Prometheus instance. Ensure you have enabled a Prometheus operator
|
||||
# before executing (see above).
|
||||
make prometheus-k8s
|
||||
|
||||
# Finally, deploy the OpenTelemetry Collector
|
||||
make otel-collector-k8s
|
||||
```
|
||||
|
||||
If you want to clean up after this, you can use the `make clean-k8s` to delete all the resources created above. Note that this will not remove the namespace. Because Kubernetes sometimes gets stuck when removing namespaces, please remove this namespace manually after all the resources inside have been deleted.
|
||||
If you want to clean up after this, you can use the `make clean-k8s` to delete
|
||||
all the resources created above. Note that this will not remove the namespace.
|
||||
Because Kubernetes sometimes gets stuck when removing namespaces, please remove
|
||||
this namespace manually after all the resources inside have been deleted,
|
||||
for example with
|
||||
|
||||
## Manual deployment
|
||||
|
||||
For manual deployments, follow the same steps as above, but instead run the `kubectl apply` yourself.
|
||||
|
||||
First, the namespace needs to be created:
|
||||
```bash
|
||||
k apply -f k8s/namespace.yaml
|
||||
kubectl delete namespaces observability
|
||||
```
|
||||
|
||||
Jaeger is then deployed via the operator, and the demo follows [these steps](https://github.com/jaegertracing/jaeger-operator#getting-started) to create it:
|
||||
```bash
|
||||
# Create the jaeger operator and necessary artifacts in ns observability
|
||||
kubectl create -n observability -f https://raw.githubusercontent.com/jaegertracing/jaeger-operator/master/deploy/crds/jaegertracing.io_jaegers_crd.yaml
|
||||
kubectl create -n observability -f https://raw.githubusercontent.com/jaegertracing/jaeger-operator/master/deploy/service_account.yaml
|
||||
kubectl create -n observability -f https://raw.githubusercontent.com/jaegertracing/jaeger-operator/master/deploy/role.yaml
|
||||
kubectl create -n observability -f https://raw.githubusercontent.com/jaegertracing/jaeger-operator/master/deploy/role_binding.yaml
|
||||
kubectl create -n observability -f https://raw.githubusercontent.com/jaegertracing/jaeger-operator/master/deploy/operator.yaml
|
||||
|
||||
# Create the cluster role & bindings
|
||||
kubectl create -f https://raw.githubusercontent.com/jaegertracing/jaeger-operator/master/deploy/cluster_role.yaml
|
||||
kubectl create -f https://raw.githubusercontent.com/jaegertracing/jaeger-operator/master/deploy/cluster_role_binding.yaml
|
||||
|
||||
# Create the Jaeger instance itself:
|
||||
kubectl apply -f k8s/jaeger/jaeger.yaml
|
||||
```
|
||||
|
||||
The OpenTelemetry Collector is contained in a single k8s file, which can be deployed with one command:
|
||||
```bash
|
||||
k8s apply -f k8s/otel-collector.yaml
|
||||
```
|
||||
|
||||
|
||||
# Configuring the OpenTelemetry Collector
|
||||
Although the above steps should deploy and configure everything, let's spend
|
||||
some time on the [configuration](./k8s/otel-collector.yaml) of the Collector.
|
||||
|
||||
Although the above steps should deploy and configure both Jaeger and the OpenTelemetry Collector, it might be worth spending some time on the [configuration](./k8s/otel-collector.yaml) of the Collector.
|
||||
|
||||
One important part here is that, in order to enable our application to send traces to the OpenTelemetry Collector, we need to first configure the otlp receiver:
|
||||
One important part here is that, in order to enable our application to send data
|
||||
to the OpenTelemetry Collector, we need to first configure the `otlp` receiver:
|
||||
|
||||
```yml
|
||||
...
|
||||
otel-collector-config: |
|
||||
receivers:
|
||||
# Make sure to add the otlp receiver.
|
||||
# Make sure to add the otlp receiver.
|
||||
# This will open up the receiver on port 55680.
|
||||
otlp:
|
||||
endpoint: 0.0.0.0:55680
|
||||
@ -86,15 +112,21 @@ One important part here is that, in order to enable our application to send trac
|
||||
...
|
||||
```
|
||||
|
||||
This will create the receiver on the Collector side, and open up port `55680` for receiving traces.
|
||||
This will create the receiver on the Collector side, and open up port `55680`
|
||||
for receiving traces.
|
||||
|
||||
The rest of the configuration is quite standard, with the only mention that we need to create the Jaeger exporter:
|
||||
The rest of the configuration is quite standard, with the only mention that we
|
||||
need to create the Jaeger and Prometheus exporters:
|
||||
|
||||
```yml
|
||||
...
|
||||
exporters:
|
||||
jaeger_grpc:
|
||||
endpoint: "jaeger-collector.observability.svc.cluster.local:14250"
|
||||
|
||||
prometheus:
|
||||
endpoint: 0.0.0.0:8889
|
||||
namespace: "testapp"
|
||||
...
|
||||
```
|
||||
|
||||
@ -113,10 +145,10 @@ spec:
|
||||
protocol: TCP
|
||||
targetPort: 55680
|
||||
nodePort: 30080
|
||||
- name: metrics # Default endpoint for metrics.
|
||||
port: 8888
|
||||
- name: metrics # Endpoint for metrics from our app.
|
||||
port: 8889
|
||||
protocol: TCP
|
||||
targetPort: 8888
|
||||
targetPort: 8889
|
||||
selector:
|
||||
component: otel-collector
|
||||
type:
|
||||
@ -126,55 +158,53 @@ spec:
|
||||
This service will bind the `55680` port used to access the otlp receiver to port `30080` on your cluster's node. By doing so, it makes it possible for us to access the Collector by using the static address `<node-ip>:30080`. In case you are running a local cluster, this will be `localhost:30080`. Note that you can also change this to a LoadBalancer or have an ingress extension for accessing the service.
|
||||
|
||||
|
||||
# Writing the demo
|
||||
# Running the code
|
||||
You can find the complete code for this example in the [main.go](./main.go)
|
||||
file. To run it, ensure you have a somewhat recent version of Go (preferably >=
|
||||
1.13) and do
|
||||
|
||||
Having the OpenTelemetry Collector started with the otlp port open for traces, and connected to Jaeger, let's look at the go app that will send traces to the Collector.
|
||||
|
||||
First, we need to create an exporter using the [otlp](https://pkg.go.dev/go.opentelemetry.io/otel/exporters/otlp?tab=doc) package:
|
||||
```go
|
||||
exp, err := otlp.NewExporter(otlp.WithInsecure(),
|
||||
// use the address of the NodePort service created above
|
||||
// <node-ip>:30080
|
||||
otlp.WithAddress("localhost:30080"),
|
||||
otlp.WithGRPCDialOption(grpc.WithBlock()))
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to create the collector exporter: %v", err)
|
||||
}
|
||||
defer func() {
|
||||
err := exp.Stop()
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to stop the exporter: %v", err)
|
||||
}
|
||||
}()
|
||||
```
|
||||
This will initialize the exporter and connect to the otlp receiver at the address that we set for the [NodePort](#opentelemetry-collector-service): `localhost:30080`.
|
||||
|
||||
Feel free to remove the blocking operation, but it might come in handy when testing the connection.
|
||||
Also, make sure to close the exporter before the app exits.
|
||||
|
||||
The next step is to create the TraceProvider:
|
||||
```go
|
||||
tp, err := sdktrace.NewProvider(
|
||||
sdktrace.WithConfig(sdktrace.Config{DefaultSampler: sdktrace.AlwaysSample()}),
|
||||
sdktrace.WithResource(resource.New(
|
||||
// the service name used to display traces in Jaeger
|
||||
kv.Key(conventions.AttributeServiceName).String("test-service"),
|
||||
)),
|
||||
sdktrace.WithSyncer(exp))
|
||||
if err != nil {
|
||||
log.Fatalf("error creating trace provider: %v\n", err)
|
||||
}
|
||||
```bash
|
||||
go run main.go
|
||||
```
|
||||
|
||||
It is important here to set the [AttributeServiceName](https://github.com/open-telemetry/opentelemetry-collector/blob/master/translator/conventions/opentelemetry.go#L20) from the `github.com/open-telemetry/opentelemetry-collector/translator/conventions` package on the resource level. This will be passed to the OpenTelemetry Collector, and used as ServiceName when exporting the traces to Jaeger.
|
||||
The example simulates an application, hard at work, computing for ten seconds
|
||||
then finishing.
|
||||
|
||||
After this, you can simply start sending traces:
|
||||
```go
|
||||
tracer := tp.Tracer("test-tracer")
|
||||
ctx, span := tracer.Start(context.Background(), "CollectorExporter-Example")
|
||||
defer span.End()
|
||||
# Viewing instrumentation data
|
||||
Now the exciting part! Let's check out the telemetry data generated by our
|
||||
sample application
|
||||
|
||||
## Jaeger UI
|
||||
First, we need to enable an ingress provider. If you've been using microk8s,
|
||||
do
|
||||
|
||||
```bash
|
||||
microk8s enable ingress
|
||||
```
|
||||
|
||||
The traces should now be visible from the Jaeger UI (if you have it installed), or thorough the jaeger-query service, under the name `test-service`.
|
||||
Then find out where the Jaeger console is living:
|
||||
```bash
|
||||
kubectl get ingress --all-namespaces
|
||||
```
|
||||
|
||||
You can find the complete code for this example in the [main.go](./main.go) file.
|
||||
For us, we get the output
|
||||
```
|
||||
NAMESPACE NAME CLASS HOSTS ADDRESS PORTS AGE
|
||||
observability jaeger-query <none> * 127.0.0.1 80 5h40m
|
||||
```
|
||||
indicating that the Jaeger UI is available at
|
||||
[http://localhost:80](http://localhost:80). Navigate there in your favorite
|
||||
web-browser to view the generated traces.
|
||||
|
||||
## Prometheus
|
||||
Unfortunately, the Prometheus operator doesn't provide a convenient
|
||||
out-of-the-box ingress route for us to use, so we'll use port-forwarding
|
||||
instead. Note: this is a quick-and-dirty solution for the sake of example.
|
||||
You *will* be attacked by shady people if you do this in production!
|
||||
|
||||
```bash
|
||||
kubectl --namespace monitoring port-forward svc/prometheus-k8s 9090
|
||||
```
|
||||
|
||||
Then navigate to [http://localhost:9090](http://localhost:9090) to view
|
||||
the Prometheus dashboard.
|
||||
|
@ -12,7 +12,7 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
# Configuration based on otel-collector k8s demo:
|
||||
# Configuration based on otel-collector k8s demo:
|
||||
# https://github.com/open-telemetry/opentelemetry-collector/blob/master/examples/k8s.yaml
|
||||
|
||||
apiVersion: v1
|
||||
@ -26,7 +26,7 @@ metadata:
|
||||
data:
|
||||
otel-collector-config: |
|
||||
receivers:
|
||||
# Make sure to add the otlp receiver.
|
||||
# Make sure to add the otlp receiver.
|
||||
# This will open up the receiver on port 55680
|
||||
otlp:
|
||||
endpoint: 0.0.0.0:55680
|
||||
@ -36,6 +36,11 @@ data:
|
||||
exporters:
|
||||
jaeger_grpc:
|
||||
endpoint: "jaeger-collector.observability.svc.cluster.local:14250"
|
||||
prometheus:
|
||||
endpoint: 0.0.0.0:8889
|
||||
namespace: "testapp"
|
||||
logging:
|
||||
|
||||
service:
|
||||
extensions: [health_check]
|
||||
pipelines:
|
||||
@ -43,6 +48,11 @@ data:
|
||||
receivers: [otlp]
|
||||
processors: []
|
||||
exporters: [jaeger_grpc]
|
||||
|
||||
metrics:
|
||||
receivers: [otlp]
|
||||
processors: []
|
||||
exporters: [prometheus, logging]
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
@ -60,9 +70,9 @@ spec:
|
||||
targetPort: 55680
|
||||
nodePort: 30080
|
||||
- name: metrics # Default endpoint for metrics.
|
||||
port: 8888
|
||||
port: 8889
|
||||
protocol: TCP
|
||||
targetPort: 8888
|
||||
targetPort: 8889
|
||||
selector:
|
||||
component: otel-collector
|
||||
type:
|
||||
@ -88,7 +98,7 @@ spec:
|
||||
metadata:
|
||||
annotations:
|
||||
prometheus.io/path: "/metrics"
|
||||
prometheus.io/port: "8888"
|
||||
prometheus.io/port: "8889"
|
||||
prometheus.io/scrape: "true"
|
||||
labels:
|
||||
app: opentelemetry
|
||||
@ -114,7 +124,7 @@ spec:
|
||||
memory: 400Mi
|
||||
ports:
|
||||
- containerPort: 55680 # Default endpoint for otlp receiver.
|
||||
- containerPort: 8888 # Default endpoint for querying metrics.
|
||||
- containerPort: 8889 # Default endpoint for querying metrics.
|
||||
volumeMounts:
|
||||
- name: otel-collector-config-vol
|
||||
mountPath: /conf
|
||||
|
43
example/otel-collector/k8s/prometheus-monitor.yaml
Normal file
43
example/otel-collector/k8s/prometheus-monitor.yaml
Normal file
@ -0,0 +1,43 @@
|
||||
# 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.
|
||||
|
||||
apiVersion: monitoring.coreos.com/v1
|
||||
kind: Prometheus
|
||||
metadata:
|
||||
labels:
|
||||
app: prometheus
|
||||
prometheus: service-prometheus
|
||||
name: service-prometheus
|
||||
namespace: monitoring
|
||||
spec:
|
||||
alerting:
|
||||
alertmanagers:
|
||||
- name: alertmanager-main
|
||||
namespace: monitoring
|
||||
port: web
|
||||
baseImage: quay.io/prometheus/prometheus
|
||||
logLevel: info
|
||||
paused: false
|
||||
replicas: 2
|
||||
retention: 2d
|
||||
routePrefix: /
|
||||
ruleSelector:
|
||||
matchLabels:
|
||||
prometheus: service-prometheus
|
||||
role: alert-rules
|
||||
serviceAccountName: prometheus-k8s
|
||||
serviceMonitorSelector:
|
||||
matchExpressions:
|
||||
- key: serviceapp
|
||||
operator: Exists
|
32
example/otel-collector/k8s/prometheus-service.yaml
Normal file
32
example/otel-collector/k8s/prometheus-service.yaml
Normal file
@ -0,0 +1,32 @@
|
||||
# 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.
|
||||
|
||||
apiVersion: monitoring.coreos.com/v1
|
||||
kind: ServiceMonitor
|
||||
metadata:
|
||||
labels:
|
||||
serviceapp: otel-collector
|
||||
name: otel-collector
|
||||
namespace: observability
|
||||
spec:
|
||||
endpoints:
|
||||
- bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token
|
||||
interval: 30s
|
||||
port: metrics
|
||||
namespaceSelector:
|
||||
matchNames:
|
||||
- observability
|
||||
selector:
|
||||
matchLabels:
|
||||
app: opentelemetry
|
@ -12,7 +12,9 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Example from otlp package: https://pkg.go.dev/go.opentelemetry.io/otel/exporters/otlp?tab=doc#example-package-Insecure
|
||||
// Example using the OTLP exporter + collector + third-party backends. For
|
||||
// information about using the exporter, see:
|
||||
// https://pkg.go.dev/go.opentelemetry.io/otel/exporters/otlp?tab=doc#example-package-Insecure
|
||||
package main
|
||||
|
||||
import (
|
||||
@ -23,53 +25,100 @@ import (
|
||||
|
||||
"google.golang.org/grpc"
|
||||
|
||||
"go.opentelemetry.io/otel/api/global"
|
||||
"go.opentelemetry.io/otel/api/kv"
|
||||
"go.opentelemetry.io/otel/api/metric"
|
||||
"go.opentelemetry.io/otel/exporters/otlp"
|
||||
"go.opentelemetry.io/otel/sdk/metric/controller/push"
|
||||
"go.opentelemetry.io/otel/sdk/metric/selector/simple"
|
||||
"go.opentelemetry.io/otel/sdk/resource"
|
||||
sdktrace "go.opentelemetry.io/otel/sdk/trace"
|
||||
|
||||
"github.com/open-telemetry/opentelemetry-collector/translator/conventions"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// If the OpenTelemetry Collector is running on a local cluster (minikube or microk8s),
|
||||
// it should be accessible through the NodePort service at the `localhost:30080` address.
|
||||
// Otherwise, replace `localhost` with the address of your cluster.
|
||||
// If you run the app inside k8s, then you can probably connect directly to the service through dns
|
||||
exp, err := otlp.NewExporter(otlp.WithInsecure(),
|
||||
otlp.WithAddress("localhost:30080"),
|
||||
otlp.WithGRPCDialOption(grpc.WithBlock()))
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to create the collector exporter: %v", err)
|
||||
}
|
||||
defer func() {
|
||||
err := exp.Stop()
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to stop the exporter: %v", err)
|
||||
}
|
||||
}()
|
||||
// Initializes an OTLP exporter, and configures the corresponding trace and
|
||||
// metric providers.
|
||||
func initProvider() (*otlp.Exporter, *push.Controller) {
|
||||
|
||||
tp, err := sdktrace.NewProvider(
|
||||
// If the OpenTelemetry Collector is running on a local cluster (minikube or
|
||||
// microk8s), it should be accessible through the NodePort service at the
|
||||
// `localhost:30080` address. Otherwise, replace `localhost` with the
|
||||
// address of your cluster. If you run the app inside k8s, then you can
|
||||
// probably connect directly to the service through dns
|
||||
exp, err := otlp.NewExporter(
|
||||
otlp.WithInsecure(),
|
||||
otlp.WithAddress("localhost:30080"),
|
||||
otlp.WithGRPCDialOption(grpc.WithBlock()), // useful for testing
|
||||
)
|
||||
handleErr(err, "failed to create exporter")
|
||||
|
||||
traceProvider, err := sdktrace.NewProvider(
|
||||
sdktrace.WithConfig(sdktrace.Config{DefaultSampler: sdktrace.AlwaysSample()}),
|
||||
sdktrace.WithResource(resource.New(
|
||||
// the service name used to display traces in Jaeger
|
||||
// the service name used to display traces in backends
|
||||
kv.Key(conventions.AttributeServiceName).String("test-service"),
|
||||
)),
|
||||
sdktrace.WithSyncer(exp))
|
||||
if err != nil {
|
||||
log.Fatalf("error creating trace provider: %v\n", err)
|
||||
sdktrace.WithSyncer(exp),
|
||||
)
|
||||
handleErr(err, "failed to create trace provider")
|
||||
|
||||
pusher := push.New(
|
||||
simple.NewWithExactDistribution(),
|
||||
exp,
|
||||
push.WithPeriod(2*time.Second),
|
||||
)
|
||||
|
||||
global.SetTraceProvider(traceProvider)
|
||||
global.SetMeterProvider(pusher.Provider())
|
||||
pusher.Start()
|
||||
|
||||
return exp, pusher
|
||||
}
|
||||
|
||||
func main() {
|
||||
log.Printf("Waiting for connection...")
|
||||
|
||||
exp, pusher := initProvider()
|
||||
defer func() { handleErr(exp.Stop(), "failed to stop exporter") }()
|
||||
defer pusher.Stop() // pushes any last exports to the receiver
|
||||
|
||||
tracer := global.Tracer("test-tracer")
|
||||
meter := global.Meter("test-meter")
|
||||
|
||||
// labels represent additional key-value descriptors that can be bound to a
|
||||
// metric observer or recorder.
|
||||
commonLabels := []kv.KeyValue{
|
||||
kv.String("labelA", "chocolate"),
|
||||
kv.String("labelB", "raspberry"),
|
||||
kv.String("labelC", "vanilla"),
|
||||
}
|
||||
|
||||
tracer := tp.Tracer("test-tracer")
|
||||
// Recorder metric example
|
||||
valuerecorder := metric.Must(meter).
|
||||
NewFloat64Counter(
|
||||
"an_important_metric",
|
||||
metric.WithDescription("Measures the cumulative epicness of the app"),
|
||||
).Bind(commonLabels...)
|
||||
defer valuerecorder.Unbind()
|
||||
|
||||
// Then use the OpenTelemetry tracing library, like we normally would.
|
||||
// work begins
|
||||
ctx, span := tracer.Start(context.Background(), "CollectorExporter-Example")
|
||||
|
||||
for i := 0; i < 10; i++ {
|
||||
_, iSpan := tracer.Start(ctx, fmt.Sprintf("Sample-%d", i))
|
||||
log.Printf("Doing really hard work (%d / 10)\n", i+1)
|
||||
valuerecorder.Add(ctx, 1.0)
|
||||
|
||||
<-time.After(time.Second)
|
||||
iSpan.End()
|
||||
}
|
||||
|
||||
log.Printf("Done!")
|
||||
span.End()
|
||||
}
|
||||
|
||||
func handleErr(err error, message string) {
|
||||
if err != nil {
|
||||
log.Fatalf("%s: %v", message, err)
|
||||
}
|
||||
}
|
||||
|
@ -1,80 +0,0 @@
|
||||
# OTLP Example
|
||||
This example demonstrates how to export trace and metric data from an
|
||||
application using OpenTelemetry's own wire protocol
|
||||
[OTLP](https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/protocol/README.md).
|
||||
We will also walk you through configuring a collector to accept OTLP exports.
|
||||
|
||||
### How to run?
|
||||
|
||||
#### Prequisites
|
||||
- go >=1.13 installed
|
||||
- OpenTelemetry collector is available
|
||||
|
||||
#### Configure the Collector
|
||||
Follow the instructions [on the
|
||||
website](https://opentelemetry.io/docs/collector/about/) to install a working
|
||||
instance of the collector. This example assumes you have the collector installed
|
||||
locally.
|
||||
|
||||
To configure the collector to accept OTLP traffic from our application,
|
||||
ensure that it has the following configs:
|
||||
|
||||
```yaml
|
||||
receivers:
|
||||
otlp:
|
||||
endpoint: 0.0.0.0:55680 # listens to localhost:55680
|
||||
|
||||
# potentially other receivers
|
||||
|
||||
service:
|
||||
pipelines:
|
||||
|
||||
traces:
|
||||
receivers:
|
||||
- otlp
|
||||
# potentially other receivers
|
||||
processors: # whatever processors you need
|
||||
exporters: # wherever you want your data to go
|
||||
|
||||
metrics:
|
||||
receivers:
|
||||
-otlp
|
||||
# potentially other receivers
|
||||
processors: etc
|
||||
exporters: etc
|
||||
|
||||
# other services
|
||||
```
|
||||
|
||||
An example config has been provided at
|
||||
[example-otlp-config.yaml](otlp/example-otlp-config.yaml).
|
||||
|
||||
Then to run:
|
||||
```sh
|
||||
./[YOUR_COLLECTOR_BINARY] --config [PATH_TO_CONFIG]
|
||||
```
|
||||
|
||||
If you use the example config, it's set to export to `stdout`. If you run
|
||||
the collector on the same machine as the example application, you should
|
||||
see trace and metric outputs from the collector.
|
||||
|
||||
#### Start the Application
|
||||
An example application is included in this directory. It simulates the process
|
||||
of scribing a spell scroll (e.g. in [D&D](https://roll20.net/compendium/dnd5e/Spell%20Scroll#content)).
|
||||
The application has been instrumented and exports both trace and metric data
|
||||
via OTLP to any listening receiver. To run it:
|
||||
|
||||
```sh
|
||||
go get -d go.opentelemetry.io/otel
|
||||
cd $GOPATH/go.opentelemetry.io/otel/example/otlp
|
||||
go run main.go
|
||||
```
|
||||
|
||||
The application is currently configured to transmit exported data to
|
||||
`localhost:55680`. See [main.go](otlp/main.go) for full details.
|
||||
|
||||
After starting the application, you should see trace and metric log output
|
||||
on the collector.
|
||||
|
||||
Note, if the receiver is incorrectly configured to take in metric data, the
|
||||
application may complain about being unable to connect.
|
@ -1,29 +0,0 @@
|
||||
extensions:
|
||||
health_check:
|
||||
|
||||
receivers:
|
||||
otlp:
|
||||
endpoint: 0.0.0.0:55680
|
||||
|
||||
processors:
|
||||
batch:
|
||||
queued_retry:
|
||||
|
||||
exporters:
|
||||
logging:
|
||||
loglevel: debug
|
||||
|
||||
service:
|
||||
|
||||
pipelines:
|
||||
|
||||
traces:
|
||||
receivers: [otlp]
|
||||
processors: [batch, queued_retry]
|
||||
exporters: [logging]
|
||||
|
||||
metrics:
|
||||
receivers: [otlp]
|
||||
exporters: [logging]
|
||||
|
||||
extensions: [health_check]
|
@ -1,13 +0,0 @@
|
||||
module go.opentelemetry.io/otel/example/otel-test
|
||||
|
||||
go 1.13
|
||||
|
||||
replace (
|
||||
go.opentelemetry.io/otel => ../..
|
||||
go.opentelemetry.io/otel/exporters/otlp => ../../exporters/otlp
|
||||
)
|
||||
|
||||
require (
|
||||
go.opentelemetry.io/otel v0.6.0
|
||||
go.opentelemetry.io/otel/exporters/otlp v0.6.0
|
||||
)
|
@ -1,126 +0,0 @@
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/DataDog/sketches-go v0.0.0-20190923095040-43f19ad77ff7 h1:qELHH0AWCvf98Yf+CNIJx9vOZOfHFDDzgDRYsnNk/vs=
|
||||
github.com/DataDog/sketches-go v0.0.0-20190923095040-43f19ad77ff7/go.mod h1:Q5DbzQ+3AkgGwymQO7aZFNP7ns2lZKGtvRBzRXfdi60=
|
||||
github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q=
|
||||
github.com/benbjohnson/clock v1.0.3 h1:vkLuvpK4fmtSCuo60+yC63p7y0BmQ8gm5ZXGuBCJyXg=
|
||||
github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls=
|
||||
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.0 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w=
|
||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.14.3 h1:OCJlWkOUoTnl0neNGlf4fUm3TmbEtguw7vR+nGtnDjY=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.14.3/go.mod h1:6CwZWGDSPRJidgKAtJVvND6soZe6fT7iteq8wDPdhb0=
|
||||
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs=
|
||||
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/open-telemetry/opentelemetry-proto v0.3.0 h1:+ASAtcayvoELyCF40+rdCMlBOhZIn5TPDez85zSYc30=
|
||||
github.com/open-telemetry/opentelemetry-proto v0.3.0/go.mod h1:PMR5GI0F7BSpio+rBGFxNm6SLzg3FypDTcFuQZnO+F8=
|
||||
github.com/opentracing/opentracing-go v1.1.1-0.20190913142402-a7454ce5950e/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20191002035440-2ec189313ef0 h1:2mqDk8w/o6UmeUCu5Qiq2y7iMf6anbx+YA8d1JFoFrs=
|
||||
golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20190927181202-20e1ac93f88c/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
|
||||
google.golang.org/genproto v0.0.0-20191009194640-548a555dbc03 h1:4HYDjxeNXAOTv3o1N2tjo8UUSlhQgAD52FVkwxnWgM8=
|
||||
google.golang.org/genproto v0.0.0-20191009194640-548a555dbc03/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA=
|
||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
google.golang.org/grpc v1.27.1 h1:zvIju4sqAGvwKspUQOhwnpcqSbzi7/H6QomNNjTL4sk=
|
||||
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.29.1 h1:EC2SB8S04d2r73uptxphDSUG+kTKVgjRPF+N3xpxRB4=
|
||||
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||
google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.7 h1:VUgggvou5XRW9mHwD/yXxIYSMtY0zoKQf/v226p2nyo=
|
||||
gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
@ -1,115 +0,0 @@
|
||||
// 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.
|
||||
//
|
||||
// Example application showcasing opentelemetry Go using the OTLP wire
|
||||
// protocol
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"go.opentelemetry.io/otel/api/global"
|
||||
"go.opentelemetry.io/otel/api/kv"
|
||||
"go.opentelemetry.io/otel/api/metric"
|
||||
"go.opentelemetry.io/otel/exporters/otlp"
|
||||
"go.opentelemetry.io/otel/sdk/metric/controller/push"
|
||||
"go.opentelemetry.io/otel/sdk/metric/selector/simple"
|
||||
sdktrace "go.opentelemetry.io/otel/sdk/trace"
|
||||
)
|
||||
|
||||
// Initializes an OTLP exporter, and configures the corresponding trace and
|
||||
// metric providers.
|
||||
func initProvider() (*otlp.Exporter, *push.Controller) {
|
||||
exp, err := otlp.NewExporter(
|
||||
otlp.WithInsecure(),
|
||||
otlp.WithAddress("localhost:55680"),
|
||||
)
|
||||
handleErr(err, "Failed to create exporter: $v")
|
||||
|
||||
traceProvider, err := sdktrace.NewProvider(
|
||||
sdktrace.WithConfig(sdktrace.Config{DefaultSampler: sdktrace.AlwaysSample()}),
|
||||
sdktrace.WithSyncer(exp),
|
||||
)
|
||||
handleErr(err, "Failed to create trace provider: %v")
|
||||
|
||||
pusher := push.New(
|
||||
simple.NewWithExactDistribution(),
|
||||
exp,
|
||||
push.WithPeriod(2*time.Second),
|
||||
)
|
||||
|
||||
global.SetTraceProvider(traceProvider)
|
||||
global.SetMeterProvider(pusher.Provider())
|
||||
pusher.Start()
|
||||
|
||||
return exp, pusher
|
||||
}
|
||||
|
||||
func main() {
|
||||
exp, pusher := initProvider()
|
||||
defer func() { handleErr(exp.Stop(), "Failed to stop exporter") }()
|
||||
defer pusher.Stop() // pushes any last exports to the receiver
|
||||
|
||||
tracer := global.Tracer("mage-sense")
|
||||
meter := global.Meter("mage-read")
|
||||
|
||||
// labels represent additional descriptors that can be bound to a metric
|
||||
// observer or recorder. In this case they describe the location in
|
||||
// which a spell scroll is scribed.
|
||||
commonLabels := []kv.KeyValue{
|
||||
kv.String("work-room", "East Scriptorium"),
|
||||
kv.String("occupancy", "69,105"),
|
||||
kv.String("priority", "Ultra"),
|
||||
}
|
||||
|
||||
// Observer metric example
|
||||
oneMetricCB := func(_ context.Context, result metric.Float64ObserverResult) {
|
||||
result.Observe(1, commonLabels...)
|
||||
}
|
||||
_ = metric.Must(meter).NewFloat64ValueObserver("scrying.glass.one", oneMetricCB,
|
||||
metric.WithDescription("A ValueObserver set to 1.0"),
|
||||
)
|
||||
|
||||
// Recorder metric example
|
||||
valuerecorder := metric.Must(meter).
|
||||
NewFloat64ValueRecorder("scrying.glass.two").
|
||||
Bind(commonLabels...)
|
||||
defer valuerecorder.Unbind()
|
||||
|
||||
// work begins
|
||||
ctx, span := tracer.Start(context.Background(), "Archmage-Overlord-Inspection")
|
||||
for i := 0; i < 10; i++ {
|
||||
_, innerSpan := tracer.Start(ctx, fmt.Sprintf("Minion-%d", i))
|
||||
log.Println("Minions hard at work, scribing...")
|
||||
valuerecorder.Record(ctx, float64(i)*1.5)
|
||||
|
||||
<-time.After(time.Second)
|
||||
innerSpan.End()
|
||||
}
|
||||
|
||||
span.End()
|
||||
<-time.After(time.Second)
|
||||
|
||||
log.Println("Spell-scroll scribed!")
|
||||
}
|
||||
|
||||
func handleErr(err error, message string) {
|
||||
if err != nil {
|
||||
log.Fatalf("%s: %v", message, err)
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user