Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Metrics stdout export pipeline #265

Merged
merged 86 commits into from
Nov 15, 2019
Merged
Show file tree
Hide file tree
Changes from 47 commits
Commits
Show all changes
86 commits
Select commit Hold shift + click to select a range
19346a4
Add MetricAggregator.Merge() implementations
jmacd Oct 30, 2019
cb9557a
Upstream
jmacd Oct 30, 2019
03f7854
Update from feedback
jmacd Oct 30, 2019
09d88a1
Type
jmacd Oct 30, 2019
865b7ab
Upstream
jmacd Oct 30, 2019
5719abe
Upstream
jmacd Oct 30, 2019
c6ca4fd
Ckpt
jmacd Oct 31, 2019
acc2450
Ckpt
jmacd Oct 31, 2019
5bebed5
Upstream
jmacd Oct 31, 2019
5b23af4
Add push controller
jmacd Oct 31, 2019
80e0df8
Ckpt
jmacd Oct 31, 2019
f533814
Upstream
jmacd Oct 31, 2019
3423242
Add aggregator interfaces, stdout encoder
jmacd Oct 31, 2019
a788631
Modify basic main.go
jmacd Oct 31, 2019
fbc50a1
Main is working
jmacd Oct 31, 2019
49aa969
Batch stdout output
jmacd Oct 31, 2019
c2c73be
Sum udpate
jmacd Oct 31, 2019
5ea9128
Rename stdout
jmacd Oct 31, 2019
f0d986c
Add stateless/stateful Batcher options
jmacd Oct 31, 2019
63d79a8
Undo a for-loop in the example, remove a done TODO
jmacd Oct 31, 2019
8716da3
Merge
jmacd Nov 3, 2019
837035d
Update imports
jmacd Nov 3, 2019
9586471
Add note
jmacd Nov 3, 2019
0c09f8c
Rename defaultkeys
jmacd Nov 4, 2019
03ff7d2
Support variable label encoder to speed OpenMetrics/Statsd export
jmacd Nov 4, 2019
88a236e
Lint
jmacd Nov 4, 2019
bf313da
Upstream
jmacd Nov 5, 2019
db41c9d
Doc
jmacd Nov 5, 2019
dd6229c
Merge
jmacd Nov 5, 2019
0bc5ffe
Precommit/lint
jmacd Nov 6, 2019
c575b08
Simplify Aggregator API
jmacd Nov 6, 2019
3be8e6e
Record->Identifier
jmacd Nov 6, 2019
214b882
Remove export.Record a.k.a. Identifier
jmacd Nov 6, 2019
048c8d9
Checkpoint
jmacd Nov 6, 2019
657c064
Propagate errors to the SDK, remove a bunch of 'TODO warn'
jmacd Nov 6, 2019
0d78cfa
Checkpoint
jmacd Nov 6, 2019
f81aa34
Introduce export.Labels
jmacd Nov 6, 2019
94580ae
Comments in export/metric.go
jmacd Nov 7, 2019
2dee926
Comment
jmacd Nov 7, 2019
e4c9dde
Merge
jmacd Nov 7, 2019
a7623d8
More merge
jmacd Nov 7, 2019
8fcfe95
More doc
jmacd Nov 7, 2019
df3b3af
Complete example
jmacd Nov 7, 2019
4121362
Lint fixes
jmacd Nov 7, 2019
41d3f7b
Add a testable example
jmacd Nov 7, 2019
72872fa
Lint
jmacd Nov 7, 2019
0160c3d
Let Export return an error
jmacd Nov 8, 2019
77e4c3f
add a basic stdout exporter test
jmacd Nov 8, 2019
dc23ae1
Add measure test; fix aggregator APIs
jmacd Nov 9, 2019
18b8340
Upstream
jmacd Nov 9, 2019
dfbc881
Use JSON numbers, not strings
jmacd Nov 9, 2019
9ecdf51
Test stdout exporter error
jmacd Nov 9, 2019
60ab98b
Add a test for the call to RangeTest
jmacd Nov 9, 2019
bf2f1e6
Add error handler API to improve correctness test; return errors from…
jmacd Nov 9, 2019
419ed4f
Undo the previous -- do not expose errors
jmacd Nov 9, 2019
0953112
Add simple selector variations, test
jmacd Nov 9, 2019
8034ebe
Repair examples
jmacd Nov 9, 2019
a472048
Test push controller error handling
jmacd Nov 9, 2019
08a26de
Add SDK label encoder tests
jmacd Nov 9, 2019
c09bd0e
Add a defaultkeys batcher test
jmacd Nov 9, 2019
9ef0a37
Add an ungrouped batcher test
jmacd Nov 9, 2019
557f912
Lint new tests
jmacd Nov 9, 2019
0133786
Respond to krnowak's feedback
jmacd Nov 10, 2019
e518398
Undo comment
jmacd Nov 12, 2019
72e3d30
Use concrete receivers for export records and labels, since the const…
jmacd Nov 12, 2019
9acdc5a
Bug fix for stateful batchers; clone an aggregator for long term storage
jmacd Nov 12, 2019
d7a5cda
Upstream
jmacd Nov 14, 2019
399c34c
Remove TODO addressed in #318
jmacd Nov 14, 2019
2a75566
Add errors to all aggregator interfaces
jmacd Nov 14, 2019
efb75ed
Handle ErrNoLastValue case in stdout exporter
jmacd Nov 14, 2019
1153503
Move aggregator API into sdk/export/metric/aggregator
jmacd Nov 15, 2019
623a63a
Update all aggregator exported-method comments
jmacd Nov 15, 2019
e298c94
Document the aggregator APIs
jmacd Nov 15, 2019
d75bc6e
More aggregator comments
jmacd Nov 15, 2019
723d084
Add multiple updates to the ungrouped test
jmacd Nov 15, 2019
8b5a4d6
Fixes for feedback from Gustavo and Liz
jmacd Nov 15, 2019
13e0580
Producer->CheckpointSet; add FinishedCollection
jmacd Nov 15, 2019
b75059e
Process takes an export.Record
jmacd Nov 15, 2019
d03709a
ReadCheckpoint->CheckpointSet
jmacd Nov 15, 2019
93fe58f
EncodeLabels->Encode
jmacd Nov 15, 2019
782cabf
Format a better inconsistent type error; add more aggregator API tests
jmacd Nov 15, 2019
eedaaab
More RangeTest test coverage
jmacd Nov 15, 2019
f67b47c
Make benbjohnson/clock a test-only dependency
jmacd Nov 15, 2019
2e7007d
Merge
jmacd Nov 15, 2019
046db4a
Handle ErrNoLastValue in stress_test
jmacd Nov 15, 2019
a294720
Upstream
jmacd Nov 15, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions example/basic/go.sum
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
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/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/OpenPeeDeeP/depguard v1.0.1/go.mod h1:xsIw86fROiiwelg+jB2uM9PiKihMMmUx/1V+TNhjQvM=
Expand All @@ -21,6 +22,7 @@ github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfc
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
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/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
Expand Down Expand Up @@ -82,6 +84,7 @@ github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
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/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
Expand All @@ -107,9 +110,11 @@ github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgo
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
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/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
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/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
Expand All @@ -136,6 +141,7 @@ github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/9
github.com/pelletier/go-toml v1.5.0/go.mod h1:5N711Q9dKgbdkxHL+MEfF31hpT7l0S0s/t2kKREewys=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
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_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
Expand Down Expand Up @@ -177,6 +183,7 @@ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/timakin/bodyclose v0.0.0-20190930140734-f7f2e9bca95e/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
Expand Down Expand Up @@ -274,6 +281,7 @@ google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRn
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/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/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
Expand All @@ -282,6 +290,7 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWD
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
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=
Expand Down
29 changes: 25 additions & 4 deletions example/basic/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,19 @@ package main
import (
"context"
"log"
"time"

"go.opentelemetry.io/otel/api/distributedcontext"
"go.opentelemetry.io/otel/api/key"
"go.opentelemetry.io/otel/api/metric"
"go.opentelemetry.io/otel/api/trace"
"go.opentelemetry.io/otel/exporter/trace/stdout"
metricstdout "go.opentelemetry.io/otel/exporter/metric/stdout"
tracestdout "go.opentelemetry.io/otel/exporter/trace/stdout"
"go.opentelemetry.io/otel/global"
metricsdk "go.opentelemetry.io/otel/sdk/metric"
"go.opentelemetry.io/otel/sdk/metric/batcher/defaultkeys"
"go.opentelemetry.io/otel/sdk/metric/controller/push"
"go.opentelemetry.io/otel/sdk/metric/selector/simple"
sdktrace "go.opentelemetry.io/otel/sdk/trace"
)

Expand All @@ -37,7 +43,7 @@ var (
// initTracer creates and registers trace provider instance.
func initTracer() {
var err error
exp, err := stdout.NewExporter(stdout.Options{PrettyPrint: false})
exp, err := tracestdout.NewExporter(tracestdout.Options{PrettyPrint: false})
if err != nil {
log.Panicf("failed to initialize stdout exporter %v\n", err)
return
Expand All @@ -50,10 +56,25 @@ func initTracer() {
global.SetTraceProvider(tp)
}

func initMeter() *push.Controller {
selector := simple.New()
exporter := metricstdout.New(metricstdout.Options{PrettyPrint: false})
batcher := defaultkeys.New(selector, metricsdk.DefaultLabelEncoder(), true)
pusher := push.New(batcher, exporter, time.Second)
pusher.Start()

global.SetMeterProvider(pusher)
return pusher
}

func main() {
defer initMeter().Stop()
initTracer()

// Note: Have to get the meter and tracer after the global is
// initialized. See OTEP 0005.

tracer := global.TraceProvider().GetTracer("ex.com/basic")
// TODO: Meter doesn't work yet, check if resources to be shared afterwards.
meter := global.MeterProvider().GetMeter("ex.com/basic")

oneMetric := meter.NewFloat64Gauge("ex.com.one",
Expand All @@ -70,7 +91,7 @@ func main() {
barKey.String("bar1"),
)

commonLabels := meter.Labels(lemonsKey.Int(10))
commonLabels := meter.Labels(lemonsKey.Int(10), key.String("A", "1"), key.String("B", "2"), key.String("C", "3"))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use of these extra labels was not obvious until I understood how everything works. Essentially they are ignored because it is using defaultkey batcher which only uses labels defined as part of metric descriptor.

Also, labels set via distributedcontext are not automatically used. It is by design but it is not obvious.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I sort of feel like throwing away this example. It's full of random, incoherent calls.


gauge := oneMetric.AcquireHandle(commonLabels)
defer gauge.Release()
Expand Down
145 changes: 145 additions & 0 deletions exporter/metric/stdout/stdout.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
// Copyright 2019, 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.

package stdout // import "go.opentelemetry.io/otel/exporter/metric/stdout"

import (
"context"
"encoding/json"
"fmt"
"os"
"strings"
"time"

export "go.opentelemetry.io/otel/sdk/export/metric"
"go.opentelemetry.io/otel/sdk/metric/aggregator"
)

type Exporter struct {
options Options
}

// Options are the options to be used when initializing a stdout export.
type Options struct {
// File is the destination. If not set, os.Stdout is used.
File *os.File

// PrettyPrint will pretty the json representation of the span,
// making it print "pretty". Default is false.
PrettyPrint bool

// DoNotPrintTime suppresses timestamp printing. This is
// useful to create testable examples or if the are being
jmacd marked this conversation as resolved.
Show resolved Hide resolved
DoNotPrintTime bool

// Quantiles are the desired aggregation quantiles for measure
// metric data, used when the configured aggregator supports
// quantiles.
//
// Note: this exporter is meant as a demonstration; a real
// exporter may wish to configure quantiles on a per-metric
// basis.
Quantiles []float64
jmacd marked this conversation as resolved.
Show resolved Hide resolved
}

type expoBatch struct {
Timestamp *time.Time `json:"time,omitempty"`
Updates []expoLine `json:"updates,omitempty"`
}

type expoLine struct {
Name string `json:"name"`
Max interface{} `json:"max,omitempty"`
Sum interface{} `json:"sum,omitempty"`
Count interface{} `json:"count,omitempty"`
LastValue interface{} `json:"last,omitempty"`

// Note: this is a pointer because omitempty doesn't work when time.IsZero()
Timestamp *time.Time `json:"time,omitempty"`
}

var _ export.Exporter = &Exporter{}
jmacd marked this conversation as resolved.
Show resolved Hide resolved

func New(options Options) *Exporter {
if options.File == nil {
options.File = os.Stdout
}
return &Exporter{
options: options,
}
}

func (e *Exporter) Export(_ context.Context, producer export.Producer) error {
var batch expoBatch
if !e.options.DoNotPrintTime {
ts := time.Now()
batch.Timestamp = &ts
}
producer.Foreach(func(record export.Record) {
desc := record.Descriptor()
labels := record.Labels()
jmacd marked this conversation as resolved.
Show resolved Hide resolved
agg := record.Aggregator()

var expose expoLine
if sum, ok := agg.(aggregator.Sum); ok {
expose.Sum = sum.Sum().Emit(desc.NumberKind())

} else if lv, ok := agg.(aggregator.LastValue); ok {
ts := lv.Timestamp()
expose.LastValue = lv.LastValue().Emit(desc.NumberKind())
expose.Timestamp = &ts
jmacd marked this conversation as resolved.
Show resolved Hide resolved

} else if msc, ok := agg.(aggregator.MaxSumCount); ok {
expose.Max = msc.Max().Emit(desc.NumberKind())
expose.Sum = msc.Sum().Emit(desc.NumberKind())
expose.Count = msc.Count().Emit(desc.NumberKind())

} else if dist, ok := agg.(aggregator.Distribution); ok {
expose.Max = dist.Max().Emit(desc.NumberKind())
expose.Sum = dist.Sum().Emit(desc.NumberKind())
expose.Count = dist.Count().Emit(desc.NumberKind())

// TODO print one configured quantile per line
}

var sb strings.Builder

sb.WriteString(desc.Name())

if labels.Len() > 0 {
sb.WriteRune('{')
sb.WriteString(labels.Encoded())
sb.WriteRune('}')
}

expose.Name = sb.String()

batch.Updates = append(batch.Updates, expose)
})

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Shouldn't you return err here first if aggErr != nil?

Otherwise you might export output when there's an error that happened as you processed the batch?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For this exporter specifically--if it is only an aggregator error not a marshal error--I figured it would be best to continue formatting the output and fill in "NaN". I figure NaN will parse as an error, but this at least yields a human-readable output. A single error is still returned, which the controller will print. I can be convinced to be less tolerant of errors though.

var data []byte
var err error
if e.options.PrettyPrint {
data, err = json.MarshalIndent(batch, "", "\t")
} else {
data, err = json.Marshal(batch)
}

if err != nil {
return err
}

fmt.Fprintln(e.options.File, string(data))
return nil
}
Loading