Generate "Golden Data" trace spans (#967)

1. PICT tool input files for trace data and resulting output files from running pict from the command line. These are in `internal/goldendataset/testdata`. See: [Pairwise Independent Combinatorial Testing](https://github.com/microsoft/pict)
2. Generator for fully-populated OLTP ResourceSpans from PICT output files.

This has all the intended functionality for this PR. It has no impact on other functionality so there should be no problem in merging to master. I will follow up with other PRs to complete full "Golden Dataset" testing functionality.

**Link to tracking Issue:** #652 

**Testing:** Unit tests exist for all functionality which has been coded so far

**Documentation:** None yet. Will do so after golden dataset generation coding is complete.
This commit is contained in:
Kevin Brockhoff 2020-05-26 11:28:53 -05:00 committed by GitHub
parent 14ae2173ee
commit ffd4838f37
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 1660 additions and 27 deletions

View File

@ -0,0 +1,105 @@
// Copyright 2020, 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 goldendataset
import (
"encoding/csv"
"io"
"os"
"path/filepath"
otlpcommon "github.com/open-telemetry/opentelemetry-proto/gen/go/common/v1"
"github.com/spf13/cast"
)
func convertMapToAttributeKeyValues(attrsMap map[string]interface{}) []*otlpcommon.AttributeKeyValue {
if attrsMap == nil {
return nil
}
attrList := make([]*otlpcommon.AttributeKeyValue, len(attrsMap))
index := 0
for key, value := range attrsMap {
attrList[index] = constructAttributeKeyValue(key, value)
index++
}
return attrList
}
func constructAttributeKeyValue(key string, value interface{}) *otlpcommon.AttributeKeyValue {
var attr otlpcommon.AttributeKeyValue
switch val := value.(type) {
case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64:
attr = otlpcommon.AttributeKeyValue{
Key: key,
Type: otlpcommon.AttributeKeyValue_INT,
IntValue: cast.ToInt64(val),
}
case float32, float64:
attr = otlpcommon.AttributeKeyValue{
Key: key,
Type: otlpcommon.AttributeKeyValue_DOUBLE,
DoubleValue: cast.ToFloat64(val),
}
case bool:
attr = otlpcommon.AttributeKeyValue{
Key: key,
Type: otlpcommon.AttributeKeyValue_BOOL,
BoolValue: cast.ToBool(val),
}
default:
attr = otlpcommon.AttributeKeyValue{
Key: key,
Type: otlpcommon.AttributeKeyValue_STRING,
StringValue: val.(string),
}
}
return &attr
}
func loadPictOutputFile(fileName string) ([][]string, error) {
file, err := os.Open(filepath.Clean(fileName))
if err != nil {
return nil, err
}
defer func() {
cerr := file.Close()
if err == nil {
err = cerr
}
}()
reader := csv.NewReader(file)
reader.Comma = '\t'
return reader.ReadAll()
}
func generateTraceID(random io.Reader) []byte {
var r [16]byte
_, err := random.Read(r[:])
if err != nil {
panic(err)
}
return r[:]
}
func generateSpanID(random io.Reader) []byte {
var r [8]byte
_, err := random.Read(r[:])
if err != nil {
panic(err)
}
return r[:]
}

View File

@ -0,0 +1,184 @@
// Copyright 2020, 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 goldendataset
//// Start of PICT inputs for generating golden dataset ResourceSpans (pict_input_traces.txt) ////
// Input columns in pict_input_traces.txt
const (
TracesColumnResource = 0
TracesColumnInstrumentationLibrary = 1
TracesColumnSpans = 2
)
// Enumerates the supported types of resource instances that can be generated.
type PICTInputResource string
const (
ResourceNil PICTInputResource = "Nil"
ResourceEmpty PICTInputResource = "Empty"
ResourceVMOnPrem PICTInputResource = "VMOnPrem"
ResourceVMCloud PICTInputResource = "VMCloud"
ResourceK8sOnPrem PICTInputResource = "K8sOnPrem"
ResourceK8sCloud PICTInputResource = "K8sCloud"
ResourceFaas PICTInputResource = "Faas"
)
// Enumerates the number and kind of instrumentation library instances that can be generated.
type PICTInputInstrumentationLibrary string
const (
LibraryNone PICTInputInstrumentationLibrary = "None"
LibraryOne PICTInputInstrumentationLibrary = "One"
LibraryTwo PICTInputInstrumentationLibrary = "Two"
)
// Enumerates the relative sizes of tracing spans that can be attached to an instrumentation library span instance.
type PICTInputSpans string
const (
LibrarySpansNone PICTInputSpans = "None"
LibrarySpansOne PICTInputSpans = "One"
LibrarySpansSeveral PICTInputSpans = "Several"
LibrarySpansAll PICTInputSpans = "All"
)
// PICTTracingInputs defines one pairwise combination of ResourceSpans variations
type PICTTracingInputs struct {
// Specifies the category of attributes to populate the Resource field with
Resource PICTInputResource
// Specifies the number and library categories to populte the InstrumentationLibrarySpans field with
InstrumentationLibrary PICTInputInstrumentationLibrary
// Specifies the relative number of spans to populate the InstrumentationLibrarySpans' Spans field with
Spans PICTInputSpans
}
//// Start of PICT inputs for generating golden dataset Spans (pict_input_spans.txt) ////
// Input columns in pict_input_spans.txt
const (
SpansColumnParent = 0
SpansColumnTracestate = 1
SpansColumnKind = 2
SpansColumnAttributes = 3
SpansColumnEvents = 4
SpansColumnLinks = 5
SpansColumnStatus = 6
)
// Enumerates the parent/child types of spans that can be generated.
type PICTInputParent string
const (
SpanParentRoot PICTInputParent = "Root"
SpanParentChild PICTInputParent = "Child"
)
// Enumerates the categories of tracestate values that can be generated for a span.
type PICTInputTracestate string
const (
TraceStateEmpty PICTInputTracestate = "Empty"
TraceStateOne PICTInputTracestate = "One"
TraceStateFour PICTInputTracestate = "Four"
)
// Enumerates the span kind values that can be set for a span.
type PICTInputKind string
const (
SpanKindUnspecified PICTInputKind = "Unspecified"
SpanKindInternal PICTInputKind = "Internal"
SpanKindServer PICTInputKind = "Server"
SpanKindClient PICTInputKind = "Client"
SpanKindProducer PICTInputKind = "Producer"
SpanKindConsumer PICTInputKind = "Consumer"
)
// Enumerates the categories of representative attributes a generated span can be populated with.
type PICTInputAttributes string
const (
SpanAttrNil PICTInputAttributes = "Nil"
SpanAttrEmpty PICTInputAttributes = "Empty"
SpanAttrDatabaseSQL PICTInputAttributes = "DatabaseSQL"
SpanAttrDatabaseNoSQL PICTInputAttributes = "DatabaseNoSQL"
SpanAttrFaaSDatasource PICTInputAttributes = "FaaSDatasource"
SpanAttrFaaSHTTP PICTInputAttributes = "FaaSHTTP"
SpanAttrFaaSPubSub PICTInputAttributes = "FaaSPubSub"
SpanAttrFaaSTimer PICTInputAttributes = "FaaSTimer"
SpanAttrFaaSOther PICTInputAttributes = "FaaSOther"
SpanAttrHTTPClient PICTInputAttributes = "HTTPClient"
SpanAttrHTTPServer PICTInputAttributes = "HTTPServer"
SpanAttrMessagingProducer PICTInputAttributes = "MessagingProducer"
SpanAttrMessagingConsumer PICTInputAttributes = "MessagingConsumer"
SpanAttrGRPCClient PICTInputAttributes = "gRPCClient"
SpanAttrGRPCServer PICTInputAttributes = "gRPCServer"
SpanAttrInternal PICTInputAttributes = "Internal"
SpanAttrMaxCount PICTInputAttributes = "MaxCount"
)
// Enumerates the categories of events and/or links a generated span can be populated with.
type PICTInputSpanChild string
const (
SpanChildCountNil PICTInputSpanChild = "Nil"
SpanChildCountEmpty PICTInputSpanChild = "Empty"
SpanChildCountOne PICTInputSpanChild = "One"
SpanChildCountTwo PICTInputSpanChild = "Two"
SpanChildCountEight PICTInputSpanChild = "Eight"
)
// Enumerates the status values a generated span can be populated with.
type PICTInputStatus string
const (
SpanStatusNil PICTInputStatus = "Nil"
SpanStatusOk PICTInputStatus = "Ok"
SpanStatusCancelled PICTInputStatus = "Cancelled"
SpanStatusUnknownError PICTInputStatus = "UnknownError"
SpanStatusInvalidArgument PICTInputStatus = "InvalidArgument"
SpanStatusDeadlineExceeded PICTInputStatus = "DeadlineExceeded"
SpanStatusNotFound PICTInputStatus = "NotFound"
SpanStatusAlreadyExists PICTInputStatus = "AlreadyExists"
SpanStatusPermissionDenied PICTInputStatus = "PermissionDenied"
SpanStatusResourceExhausted PICTInputStatus = "ResourceExhausted"
SpanStatusFailedPrecondition PICTInputStatus = "FailedPrecondition"
SpanStatusAborted PICTInputStatus = "Aborted"
SpanStatusOutOfRange PICTInputStatus = "OutOfRange"
SpanStatusUnimplemented PICTInputStatus = "Unimplemented"
SpanStatusInternalError PICTInputStatus = "InternalError"
SpanStatusUnavailable PICTInputStatus = "Unavailable"
SpanStatusDataLoss PICTInputStatus = "DataLoss"
SpanStatusUnauthenticated PICTInputStatus = "Unauthenticated"
)
// PICTSpanInputs defines one pairwise combination of Span variations
type PICTSpanInputs struct {
// Specifies whether the ParentSpanId field should be populated or not
Parent PICTInputParent
// Specifies the category of contents to populate the TraceState field with
Tracestate PICTInputTracestate
// Specifies the value to populate the Kind field with
Kind PICTInputKind
// Specifies the category of values to populate the Attributes field with
Attributes PICTInputAttributes
// Specifies the category of contents to populate the Events field with
Events PICTInputSpanChild
// Specifies the category of contents to populate the Links field with
Links PICTInputSpanChild
// Specifies the value to populate the Status field with
Status PICTInputStatus
}

View File

@ -0,0 +1,144 @@
// Copyright 2020, 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 goldendataset
import (
otlpresource "github.com/open-telemetry/opentelemetry-proto/gen/go/resource/v1"
"go.opentelemetry.io/collector/translator/conventions"
)
//GenerateResource generates a OTLP Resource object with representative attributes for the
//underlying resource type specified by the rscID input parameter.
func GenerateResource(rscID PICTInputResource) *otlpresource.Resource {
var attrs map[string]interface{}
switch rscID {
case ResourceNil:
attrs = generateNilAttributes()
case ResourceEmpty:
attrs = generateEmptyAttributes()
case ResourceVMOnPrem:
attrs = generateOnpremVMAttributes()
case ResourceVMCloud:
attrs = generateCloudVMAttributes()
case ResourceK8sOnPrem:
attrs = generateOnpremK8sAttributes()
case ResourceK8sCloud:
attrs = generateCloudK8sAttributes()
case ResourceFaas:
attrs = generateFassAttributes()
default:
attrs = generateEmptyAttributes()
}
var dropped uint32
if len(attrs) < 10 {
dropped = 0
} else {
dropped = uint32(len(attrs) % 4)
}
return &otlpresource.Resource{
Attributes: convertMapToAttributeKeyValues(attrs),
DroppedAttributesCount: dropped,
}
}
func generateNilAttributes() map[string]interface{} {
return nil
}
func generateEmptyAttributes() map[string]interface{} {
attrMap := make(map[string]interface{})
return attrMap
}
func generateOnpremVMAttributes() map[string]interface{} {
attrMap := make(map[string]interface{})
attrMap[conventions.AttributeServiceName] = "customers"
attrMap[conventions.AttributeServiceNamespace] = "production"
attrMap[conventions.AttributeServiceVersion] = "semver:0.7.3"
attrMap[conventions.AttributeHostHostname] = "tc-prod9.internal.example.com"
attrMap[conventions.AttributeHostName] = "172.18.36.18"
attrMap[conventions.AttributeHostImageID] = "661ADFA6-E293-4870-9EFA-1AA052C49F18"
attrMap[conventions.AttributeTelemetrySDKLanguage] = "java"
attrMap[conventions.AttributeTelemetrySDKName] = "opentelemetry"
attrMap[conventions.AttributeTelemetrySDKVersion] = "0.3.0"
return attrMap
}
func generateCloudVMAttributes() map[string]interface{} {
attrMap := make(map[string]interface{})
attrMap[conventions.AttributeServiceName] = "shoppingcart"
attrMap[conventions.AttributeServiceName] = "customers"
attrMap[conventions.AttributeServiceNamespace] = "production"
attrMap[conventions.AttributeServiceVersion] = "semver:0.7.3"
attrMap[conventions.AttributeTelemetrySDKLanguage] = "java"
attrMap[conventions.AttributeTelemetrySDKName] = "opentelemetry"
attrMap[conventions.AttributeTelemetrySDKVersion] = "0.3.0"
attrMap[conventions.AttributeHostHostname] = "env-check"
attrMap[conventions.AttributeHostID] = "57e8add1f79a454bae9fb1f7756a009a"
attrMap[conventions.AttributeHostName] = "10.0.0.4"
attrMap[conventions.AttributeHostImageID] = "5.3.0-1020-azure"
attrMap[conventions.AttributeHostType] = "B1ms"
attrMap[conventions.AttributeCloudProvider] = "azure"
attrMap[conventions.AttributeCloudAccount] = "2f5b8278-4b80-4930-a6bb-d86fc63a2534"
attrMap[conventions.AttributeCloudRegion] = "South Central US"
return attrMap
}
func generateOnpremK8sAttributes() map[string]interface{} {
attrMap := make(map[string]interface{})
attrMap[conventions.AttributeContainerName] = "cert-manager"
attrMap[conventions.AttributeContainerImage] = "quay.io/jetstack/cert-manager-controller:v0.14.2"
attrMap[conventions.AttributeK8sCluster] = "docker-desktop"
attrMap[conventions.AttributeK8sNamespace] = "cert-manager"
attrMap[conventions.AttributeK8sDeployment] = "cm-1-cert-manager"
attrMap[conventions.AttributeK8sPod] = "cm-1-cert-manager-6448b4949b-t2jtd"
attrMap[conventions.AttributeHostHostname] = "docker-desktop"
attrMap[conventions.AttributeHostName] = "192.168.65.3"
return attrMap
}
func generateCloudK8sAttributes() map[string]interface{} {
attrMap := make(map[string]interface{})
attrMap[conventions.AttributeContainerName] = "otel-collector"
attrMap[conventions.AttributeContainerImage] = "otel/opentelemetry-collector-contrib"
attrMap[conventions.AttributeContainerTag] = "0.4.0"
attrMap[conventions.AttributeK8sCluster] = "erp-dev"
attrMap[conventions.AttributeK8sNamespace] = "monitoring"
attrMap[conventions.AttributeK8sDeployment] = "otel-collector"
attrMap[conventions.AttributeK8sPod] = "otel-collector-6484db5844-c6f9m"
attrMap[conventions.AttributeHostHostname] = "ip-10-99-118-157.ec2.internal"
attrMap[conventions.AttributeHostID] = "ec2e3fdaffa294348bdf355156b94cda"
attrMap[conventions.AttributeHostName] = "10.99.118.157"
attrMap[conventions.AttributeHostImageID] = "ami-011c865bf7da41a9d"
attrMap[conventions.AttributeHostType] = "m5.xlarge"
attrMap[conventions.AttributeCloudProvider] = "aws"
attrMap[conventions.AttributeCloudAccount] = "12345678901"
attrMap[conventions.AttributeCloudRegion] = "us-east-1"
attrMap[conventions.AttributeCloudZone] = "us-east-1c"
return attrMap
}
func generateFassAttributes() map[string]interface{} {
attrMap := make(map[string]interface{})
attrMap[conventions.AttributeFaasID] = "https://us-central1-dist-system-demo.cloudfunctions.net/env-vars-print"
attrMap[conventions.AttributeFaasName] = "env-vars-print"
attrMap[conventions.AttributeFaasVersion] = "semver:1.0.0"
attrMap[conventions.AttributeCloudProvider] = "gcp"
attrMap[conventions.AttributeCloudAccount] = "opentelemetry"
attrMap[conventions.AttributeCloudRegion] = "us-central1"
attrMap[conventions.AttributeCloudZone] = "us-central1-a"
return attrMap
}

View File

@ -0,0 +1,49 @@
// Copyright 2020, 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 goldendataset
import (
"testing"
"github.com/golang/protobuf/proto"
otlpresource "github.com/open-telemetry/opentelemetry-proto/gen/go/resource/v1"
"github.com/stretchr/testify/assert"
)
func TestGenerateResource(t *testing.T) {
resourceIds := []PICTInputResource{ResourceNil, ResourceEmpty, ResourceVMOnPrem, ResourceVMCloud, ResourceK8sOnPrem,
ResourceK8sCloud, ResourceFaas}
for _, rscID := range resourceIds {
rsc := GenerateResource(rscID)
if rscID == ResourceNil {
assert.Nil(t, rsc.Attributes)
} else {
assert.NotNil(t, rsc.Attributes)
}
// test marshal/unmarshal
bytes, err := proto.Marshal(rsc)
if err != nil {
assert.Fail(t, err.Error())
}
if len(bytes) > 0 {
copy := &otlpresource.Resource{}
err = proto.Unmarshal(bytes, copy)
if err != nil {
assert.Fail(t, err.Error())
}
assert.EqualValues(t, len(rsc.Attributes), len(copy.Attributes))
}
}
}

View File

@ -0,0 +1,514 @@
// Copyright 2020, 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 goldendataset
import (
"fmt"
"io"
"time"
otlpcommon "github.com/open-telemetry/opentelemetry-proto/gen/go/common/v1"
otlptrace "github.com/open-telemetry/opentelemetry-proto/gen/go/trace/v1"
"go.opentelemetry.io/collector/translator/conventions"
)
var statusCodeMap = map[PICTInputStatus]otlptrace.Status_StatusCode{
SpanStatusOk: otlptrace.Status_Ok,
SpanStatusCancelled: otlptrace.Status_Cancelled,
SpanStatusUnknownError: otlptrace.Status_UnknownError,
SpanStatusInvalidArgument: otlptrace.Status_InvalidArgument,
SpanStatusDeadlineExceeded: otlptrace.Status_DeadlineExceeded,
SpanStatusNotFound: otlptrace.Status_NotFound,
SpanStatusAlreadyExists: otlptrace.Status_AlreadyExists,
SpanStatusPermissionDenied: otlptrace.Status_PermissionDenied,
SpanStatusResourceExhausted: otlptrace.Status_ResourceExhausted,
SpanStatusFailedPrecondition: otlptrace.Status_FailedPrecondition,
SpanStatusAborted: otlptrace.Status_Aborted,
SpanStatusOutOfRange: otlptrace.Status_OutOfRange,
SpanStatusUnimplemented: otlptrace.Status_Unimplemented,
SpanStatusInternalError: otlptrace.Status_InternalError,
SpanStatusUnavailable: otlptrace.Status_Unavailable,
SpanStatusDataLoss: otlptrace.Status_DataLoss,
SpanStatusUnauthenticated: otlptrace.Status_Unauthenticated,
}
var statusMsgMap = map[PICTInputStatus]string{
SpanStatusOk: "",
SpanStatusCancelled: "Cancellation received",
SpanStatusUnknownError: "",
SpanStatusInvalidArgument: "parameter is required",
SpanStatusDeadlineExceeded: "timed out after 30002 ms",
SpanStatusNotFound: "/dragons/RomanianLonghorn not found",
SpanStatusAlreadyExists: "/dragons/Drogon already exists",
SpanStatusPermissionDenied: "tlannister does not have write permission",
SpanStatusResourceExhausted: "ResourceExhausted",
SpanStatusFailedPrecondition: "33a64df551425fcc55e4d42a148795d9f25f89d4 has been edited",
SpanStatusAborted: "",
SpanStatusOutOfRange: "Range Not Satisfiable",
SpanStatusUnimplemented: "Unimplemented",
SpanStatusInternalError: "java.lang.NullPointerException",
SpanStatusUnavailable: "RecommendationService is currently unavailable",
SpanStatusDataLoss: "",
SpanStatusUnauthenticated: "nstark is unknown user",
}
//GenerateSpans generates a slice of OTLP Span objects with the number of spans specified by the count input
//parameter. The startPos parameter specifies the line in the PICT tool-generated, test parameter
//combination records file specified by the pictFile parameter to start reading from. When the end record
//is reached it loops back to the first record. The random parameter injects the random number generator
//to use in generating IDs and other random values. Using a random number generator with the same seed value
//enables reproducible tests.
//
//The return values are the slice with the generated spans, the starting position for the next generation
//run and the error which caused the spans generation to fail. If err is not nil, the spans slice will
//have nil values.
func GenerateSpans(count int, startPos int, pictFile string, random io.Reader) ([]*otlptrace.Span, int, error) {
pairsData, err := loadPictOutputFile(pictFile)
if err != nil {
return nil, 0, err
}
pairsTotal := len(pairsData)
spanList := make([]*otlptrace.Span, count)
index := startPos + 1
var inputs []string
var spanInputs *PICTSpanInputs
var traceID []byte
var parentID []byte
for i := 0; i < count; i++ {
if index >= pairsTotal {
index = 1
}
inputs = pairsData[index]
spanInputs = &PICTSpanInputs{
Parent: PICTInputParent(inputs[SpansColumnParent]),
Tracestate: PICTInputTracestate(inputs[SpansColumnTracestate]),
Kind: PICTInputKind(inputs[SpansColumnKind]),
Attributes: PICTInputAttributes(inputs[SpansColumnAttributes]),
Events: PICTInputSpanChild(inputs[SpansColumnEvents]),
Links: PICTInputSpanChild(inputs[SpansColumnLinks]),
Status: PICTInputStatus(inputs[SpansColumnStatus]),
}
switch spanInputs.Parent {
case SpanParentRoot:
traceID = generateTraceID(random)
parentID = nil
case SpanParentChild:
// use existing if available
if traceID == nil {
traceID = generateTraceID(random)
}
if parentID == nil {
parentID = generateSpanID(random)
}
}
spanName := generateSpanName(spanInputs)
spanList[i] = GenerateSpan(traceID, parentID, spanName, spanInputs, random)
parentID = spanList[i].SpanId
index++
}
return spanList, index, nil
}
func generateSpanName(spanInputs *PICTSpanInputs) string {
return fmt.Sprintf("/%s/%s/%s/%s/%s/%s/%s", spanInputs.Parent, spanInputs.Tracestate, spanInputs.Kind,
spanInputs.Attributes, spanInputs.Events, spanInputs.Links, spanInputs.Status)
}
//GenerateSpan generates a single OTLP Span based on the input values provided. They are:
// traceID - the trace ID to use, should not be nil
// parentID - the parent span ID or nil if it is a root span
// spanName - the span name, should not be blank
// spanInputs - the pairwise combination of field value variations for this span
// random - the random number generator to use in generating ID values
//
//The generated span is returned.
func GenerateSpan(traceID []byte, parentID []byte, spanName string, spanInputs *PICTSpanInputs,
random io.Reader) *otlptrace.Span {
endTime := time.Now().Add(-50 * time.Microsecond)
return &otlptrace.Span{
TraceId: traceID,
SpanId: generateSpanID(random),
TraceState: generateTraceState(spanInputs.Tracestate),
ParentSpanId: parentID,
Name: spanName,
Kind: lookupSpanKind(spanInputs.Kind),
StartTimeUnixNano: uint64(endTime.Add(-215 * time.Millisecond).UnixNano()),
EndTimeUnixNano: uint64(endTime.UnixNano()),
Attributes: generateSpanAttributes(spanInputs.Attributes),
DroppedAttributesCount: 0,
Events: generateSpanEvents(spanInputs.Events),
DroppedEventsCount: 0,
Links: generateSpanLinks(spanInputs.Links, random),
DroppedLinksCount: 0,
Status: generateStatus(spanInputs.Status),
}
}
func generateTraceState(tracestate PICTInputTracestate) string {
switch tracestate {
case TraceStateOne:
return "lasterror=f39cd56cc44274fd5abd07ef1164246d10ce2955"
case TraceStateFour:
return "err@ck=80ee5638,rate@ck=1.62,rojo=00f067aa0ba902b7,congo=t61rcWkgMzE"
case TraceStateEmpty:
fallthrough
default:
return ""
}
}
func lookupSpanKind(kind PICTInputKind) otlptrace.Span_SpanKind {
switch kind {
case SpanKindClient:
return otlptrace.Span_CLIENT
case SpanKindServer:
return otlptrace.Span_SERVER
case SpanKindProducer:
return otlptrace.Span_PRODUCER
case SpanKindConsumer:
return otlptrace.Span_CONSUMER
case SpanKindInternal:
return otlptrace.Span_INTERNAL
case SpanKindUnspecified:
fallthrough
default:
return otlptrace.Span_SPAN_KIND_UNSPECIFIED
}
}
func generateSpanAttributes(spanTypeID PICTInputAttributes) []*otlpcommon.AttributeKeyValue {
var attrs map[string]interface{}
switch spanTypeID {
case SpanAttrNil:
attrs = nil
case SpanAttrEmpty:
attrs = make(map[string]interface{})
case SpanAttrDatabaseSQL:
attrs = generateDatabaseSQLAttributes()
case SpanAttrDatabaseNoSQL:
attrs = generateDatabaseNoSQLAttributes()
case SpanAttrFaaSDatasource:
attrs = generateFaaSDatasourceAttributes()
case SpanAttrFaaSHTTP:
attrs = generateFaaSHTTPAttributes()
case SpanAttrFaaSPubSub:
attrs = generateFaaSPubSubAttributes()
case SpanAttrFaaSTimer:
attrs = generateFaaSTimerAttributes()
case SpanAttrFaaSOther:
attrs = generateFaaSOtherAttributes()
case SpanAttrHTTPClient:
attrs = generateHTTPClientAttributes()
case SpanAttrHTTPServer:
attrs = generateHTTPServerAttributes()
case SpanAttrMessagingProducer:
attrs = generateMessagingProducerAttributes()
case SpanAttrMessagingConsumer:
attrs = generateMessagingConsumerAttributes()
case SpanAttrGRPCClient:
attrs = generateGRPCClientAttributes()
case SpanAttrGRPCServer:
attrs = generateGRPCServerAttributes()
case SpanAttrInternal:
attrs = generateInternalAttributes()
case SpanAttrMaxCount:
attrs = generateMaxCountAttributes()
default:
attrs = generateGRPCClientAttributes()
}
return convertMapToAttributeKeyValues(attrs)
}
func generateStatus(statusStr PICTInputStatus) *otlptrace.Status {
if SpanStatusNil == statusStr {
return nil
}
return &otlptrace.Status{
Code: statusCodeMap[statusStr],
Message: statusMsgMap[statusStr],
}
}
func generateDatabaseSQLAttributes() map[string]interface{} {
attrMap := make(map[string]interface{})
attrMap[conventions.AttributeDBType] = "sql"
attrMap[conventions.AttributeDBInstance] = "inventory"
attrMap[conventions.AttributeDBStatement] =
"SELECT c.product_catg_id, c.catg_name, c.description, c.html_frag, c.image_url, p.name FROM product_catg c OUTER JOIN product p ON c.product_catg_id=p.product_catg_id WHERE c.product_catg_id = :catgId"
attrMap[conventions.AttributeDBUser] = "invsvc"
attrMap[conventions.AttributeDBURL] = "jdbc:postgresql://invdev.cdsr3wfqepqo.us-east-1.rds.amazonaws.com:5432/inventory"
attrMap[conventions.AttributeNetPeerIP] = "172.30.2.7"
attrMap[conventions.AttributeNetPeerPort] = int64(5432)
attrMap[conventions.AttributeEnduserID] = "unittest"
return attrMap
}
func generateDatabaseNoSQLAttributes() map[string]interface{} {
attrMap := make(map[string]interface{})
attrMap[conventions.AttributeDBType] = "cosmosdb"
attrMap[conventions.AttributeDBInstance] = "graphdb"
attrMap[conventions.AttributeDBStatement] = "g.V().hasLabel('postive').has('age', gt(65)).values('geocode')"
attrMap[conventions.AttributeDBURL] = "wss://contacttrace.gremlin.cosmos.azure.com:443/"
attrMap[conventions.AttributeNetPeerIP] = "10.118.17.63"
attrMap[conventions.AttributeNetPeerPort] = int64(443)
attrMap[conventions.AttributeEnduserID] = "unittest"
return attrMap
}
func generateFaaSDatasourceAttributes() map[string]interface{} {
attrMap := make(map[string]interface{})
attrMap[conventions.AttributeFaaSTrigger] = conventions.FaaSTriggerDataSource
attrMap[conventions.AttributeFaaSExecution] = "DB85AF51-5E13-473D-8454-1E2D59415EAB"
attrMap[conventions.AttributeFaaSDocumentCollection] = "faa-flight-delay-information-incoming"
attrMap[conventions.AttributeFaaSDocumentOperation] = "insert"
attrMap[conventions.AttributeFaaSDocumentTime] = "2020-05-09T19:50:06Z"
attrMap[conventions.AttributeFaaSDocumentName] = "delays-20200509-13.csv"
attrMap[conventions.AttributeEnduserID] = "unittest"
return attrMap
}
func generateFaaSHTTPAttributes() map[string]interface{} {
attrMap := make(map[string]interface{})
attrMap[conventions.AttributeFaaSTrigger] = conventions.FaaSTriggerHTTP
attrMap[conventions.AttributeHTTPMethod] = "POST"
attrMap[conventions.AttributeHTTPScheme] = "https"
attrMap[conventions.AttributeHTTPHost] = "api.opentelemetry.io"
attrMap[conventions.AttributeHTTPTarget] = "/blog/posts"
attrMap[conventions.AttributeHTTPFlavor] = "2"
attrMap[conventions.AttributeHTTPStatusCode] = int64(201)
attrMap[conventions.AttributeHTTPUserAgent] =
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1 Safari/605.1.15"
attrMap[conventions.AttributeEnduserID] = "unittest"
return attrMap
}
func generateFaaSPubSubAttributes() map[string]interface{} {
attrMap := make(map[string]interface{})
attrMap[conventions.AttributeFaaSTrigger] = conventions.FaaSTriggerPubSub
attrMap[conventions.AttributeMessagingSystem] = "sqs"
attrMap[conventions.AttributeMessagingDestination] = "video-views-au"
attrMap[conventions.AttributeMessagingOperation] = "process"
attrMap[conventions.AttributeEnduserID] = "unittest"
return attrMap
}
func generateFaaSTimerAttributes() map[string]interface{} {
attrMap := make(map[string]interface{})
attrMap[conventions.AttributeFaaSTrigger] = conventions.FaaSTriggerTimer
attrMap[conventions.AttributeFaaSExecution] = "73103A4C-E22F-4493-BDE8-EAE5CAB37B50"
attrMap[conventions.AttributeFaaSTime] = "2020-05-09T20:00:08Z"
attrMap[conventions.AttributeFaaSCron] = "0/15 * * * *"
attrMap[conventions.AttributeEnduserID] = "unittest"
return attrMap
}
func generateFaaSOtherAttributes() map[string]interface{} {
attrMap := make(map[string]interface{})
attrMap[conventions.AttributeFaaSTrigger] = conventions.FaaSTriggerOther
attrMap["processed.count"] = int64(256)
attrMap["processed.data"] = 14.46
attrMap["processed.errors"] = false
attrMap[conventions.AttributeEnduserID] = "unittest"
return attrMap
}
func generateHTTPClientAttributes() map[string]interface{} {
attrMap := make(map[string]interface{})
attrMap[conventions.AttributeHTTPMethod] = "GET"
attrMap[conventions.AttributeHTTPURL] = "https://opentelemetry.io/registry/"
attrMap[conventions.AttributeHTTPStatusCode] = int64(200)
attrMap[conventions.AttributeHTTPStatusText] = "More Than OK"
attrMap[conventions.AttributeEnduserID] = "unittest"
return attrMap
}
func generateHTTPServerAttributes() map[string]interface{} {
attrMap := make(map[string]interface{})
attrMap[conventions.AttributeHTTPMethod] = "POST"
attrMap[conventions.AttributeHTTPScheme] = "https"
attrMap[conventions.AttributeHTTPServerName] = "api22.opentelemetry.io"
attrMap[conventions.AttributeNetHostPort] = int64(443)
attrMap[conventions.AttributeHTTPTarget] = "/blog/posts"
attrMap[conventions.AttributeHTTPFlavor] = "2"
attrMap[conventions.AttributeHTTPStatusCode] = int64(201)
attrMap[conventions.AttributeHTTPUserAgent] =
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36"
attrMap[conventions.AttributeHTTPRoute] = "/blog/posts"
attrMap[conventions.AttributeHTTPClientIP] = "2001:506:71f0:16e::1"
attrMap[conventions.AttributeEnduserID] = "unittest"
return attrMap
}
func generateMessagingProducerAttributes() map[string]interface{} {
attrMap := make(map[string]interface{})
attrMap[conventions.AttributeMessagingSystem] = "nats"
attrMap[conventions.AttributeMessagingDestination] = "time.us.east.atlanta"
attrMap[conventions.AttributeMessagingDestinationKind] = "topic"
attrMap[conventions.AttributeMessagingMessageID] = "AA7C5438-D93A-43C8-9961-55613204648F"
attrMap["messaging.sequence"] = int64(1)
attrMap[conventions.AttributeNetPeerIP] = "10.10.212.33"
attrMap[conventions.AttributeEnduserID] = "unittest"
return attrMap
}
func generateMessagingConsumerAttributes() map[string]interface{} {
attrMap := make(map[string]interface{})
attrMap[conventions.AttributeMessagingSystem] = "kafka"
attrMap[conventions.AttributeMessagingDestination] = "infrastructure-events-zone1"
attrMap[conventions.AttributeMessagingOperation] = "receive"
attrMap[conventions.AttributeNetPeerIP] = "2600:1700:1f00:11c0:4de0:c223:a800:4e87"
attrMap[conventions.AttributeEnduserID] = "unittest"
return attrMap
}
func generateGRPCClientAttributes() map[string]interface{} {
attrMap := make(map[string]interface{})
attrMap[conventions.AttributeRPCService] = "PullRequestsService"
attrMap[conventions.AttributeNetPeerIP] = "2600:1700:1f00:11c0:4de0:c223:a800:4e87"
attrMap[conventions.AttributeNetHostPort] = int64(8443)
attrMap[conventions.AttributeEnduserID] = "unittest"
return attrMap
}
func generateGRPCServerAttributes() map[string]interface{} {
attrMap := make(map[string]interface{})
attrMap[conventions.AttributeRPCService] = "PullRequestsService"
attrMap[conventions.AttributeNetPeerIP] = "192.168.1.70"
attrMap[conventions.AttributeEnduserID] = "unittest"
return attrMap
}
func generateInternalAttributes() map[string]interface{} {
attrMap := make(map[string]interface{})
attrMap["parameters"] = "account=7310,amount=1817.10"
attrMap[conventions.AttributeEnduserID] = "unittest"
return attrMap
}
func generateMaxCountAttributes() map[string]interface{} {
attrMap := make(map[string]interface{})
attrMap[conventions.AttributeHTTPMethod] = "POST"
attrMap[conventions.AttributeHTTPScheme] = "https"
attrMap[conventions.AttributeHTTPHost] = "api.opentelemetry.io"
attrMap[conventions.AttributeNetHostName] = "api22.opentelemetry.io"
attrMap[conventions.AttributeNetHostIP] = "2600:1700:1f00:11c0:1ced:afa5:fd88:9d48"
attrMap[conventions.AttributeNetHostPort] = int64(443)
attrMap[conventions.AttributeHTTPTarget] = "/blog/posts"
attrMap[conventions.AttributeHTTPFlavor] = "2"
attrMap[conventions.AttributeHTTPStatusCode] = int64(201)
attrMap[conventions.AttributeHTTPStatusText] = "Created"
attrMap[conventions.AttributeHTTPUserAgent] =
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36"
attrMap[conventions.AttributeHTTPRoute] = "/blog/posts"
attrMap[conventions.AttributeHTTPClientIP] = "2600:1700:1f00:11c0:1ced:afa5:fd77:9d01"
attrMap[conventions.AttributeNetPeerIP] = "2600:1700:1f00:11c0:1ced:afa5:fd77:9ddc"
attrMap[conventions.AttributeNetPeerPort] = int64(39111)
attrMap["ai-sampler.weight"] = float64(0.07)
attrMap["ai-sampler.absolute"] = false
attrMap["ai-sampler.maxhops"] = int64(6)
attrMap["application.create.location"] = "https://api.opentelemetry.io/blog/posts/806673B9-4F4D-4284-9635-3A3E3E3805BE"
attrMap["application.svcmap"] = "Blogosphere"
attrMap["application.abflags"] = "UIx=false,UI4=true,flow-alt3=false"
attrMap["application.thread"] = "proc-pool-14"
attrMap["application.session"] = "233CC260-63A8-4ACA-A1C1-8F97AB4A2C01"
attrMap["application.persist.size"] = int64(1172184)
attrMap["application.queue.size"] = int64(0)
attrMap["application.validation.results"] = "Success"
attrMap["application.job.id"] = "0E38800B-9C4C-484E-8F2B-C7864D854321"
attrMap["application.service.sla"] = float64(0.34)
attrMap["application.service.slo"] = float64(0.55)
attrMap[conventions.AttributeEnduserID] = "unittest"
attrMap[conventions.AttributeEnduserRole] = "poweruser"
attrMap[conventions.AttributeEnduserScope] = "email profile administrator"
return attrMap
}
func generateSpanEvents(eventCnt PICTInputSpanChild) []*otlptrace.Span_Event {
if SpanChildCountNil == eventCnt {
return nil
}
listSize := calculateListSize(eventCnt)
eventList := make([]*otlptrace.Span_Event, listSize)
for i := 0; i < listSize; i++ {
eventList[i] = generateSpanEvent(i)
}
return eventList
}
func generateSpanLinks(linkCnt PICTInputSpanChild, random io.Reader) []*otlptrace.Span_Link {
if SpanChildCountNil == linkCnt {
return nil
}
listSize := calculateListSize(linkCnt)
linkList := make([]*otlptrace.Span_Link, listSize)
for i := 0; i < listSize; i++ {
linkList[i] = generateSpanLink(i, random)
}
return linkList
}
func calculateListSize(listCnt PICTInputSpanChild) int {
switch listCnt {
case SpanChildCountOne:
return 1
case SpanChildCountTwo:
return 2
case SpanChildCountEight:
return 8
case SpanChildCountEmpty:
fallthrough
default:
return 0
}
}
func generateSpanEvent(index int) *otlptrace.Span_Event {
t := time.Now().Add(-75 * time.Microsecond)
return &otlptrace.Span_Event{
TimeUnixNano: uint64(t.UnixNano()),
Name: "message",
Attributes: generateEventAttributes(index),
DroppedAttributesCount: 0,
}
}
func generateEventAttributes(index int) []*otlpcommon.AttributeKeyValue {
attrMap := make(map[string]interface{})
if index%2 == 0 {
attrMap[conventions.AttributeMessageType] = "SENT"
} else {
attrMap[conventions.AttributeMessageType] = "RECEIVED"
}
attrMap[conventions.AttributeMessageID] = int64(index)
attrMap[conventions.AttributeMessageCompressedSize] = int64(17 * index)
attrMap[conventions.AttributeMessageUncompressedSize] = int64(24 * index)
return convertMapToAttributeKeyValues(attrMap)
}
func generateSpanLink(index int, random io.Reader) *otlptrace.Span_Link {
return &otlptrace.Span_Link{
TraceId: generateTraceID(random),
SpanId: generateSpanID(random),
TraceState: "",
Attributes: generateLinkAttributes(index),
DroppedAttributesCount: 0,
}
}
func generateLinkAttributes(index int) []*otlpcommon.AttributeKeyValue {
attrMap := generateMessagingConsumerAttributes()
return convertMapToAttributeKeyValues(attrMap)
}

View File

@ -0,0 +1,78 @@
// Copyright 2020, 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 goldendataset
import (
"crypto/rand"
"testing"
otlptrace "github.com/open-telemetry/opentelemetry-proto/gen/go/trace/v1"
"github.com/stretchr/testify/assert"
)
func TestGenerateParentSpan(t *testing.T) {
random := rand.Reader
traceID := generateTraceID(random)
spanInputs := &PICTSpanInputs{
Parent: SpanParentRoot,
Tracestate: TraceStateEmpty,
Kind: SpanKindServer,
Attributes: SpanAttrHTTPServer,
Events: SpanChildCountTwo,
Links: SpanChildCountOne,
Status: SpanStatusOk,
}
span := GenerateSpan(traceID, nil, "/gotest-parent", spanInputs, random)
assert.Equal(t, traceID, span.TraceId)
assert.Nil(t, span.ParentSpanId)
assert.Equal(t, 11, len(span.Attributes))
assert.Equal(t, otlptrace.Status_Ok, span.Status.Code)
}
func TestGenerateChildSpan(t *testing.T) {
random := rand.Reader
traceID := generateTraceID(random)
parentID := generateSpanID(random)
spanInputs := &PICTSpanInputs{
Parent: SpanParentChild,
Tracestate: TraceStateEmpty,
Kind: SpanKindClient,
Attributes: SpanAttrDatabaseSQL,
Events: SpanChildCountEmpty,
Links: SpanChildCountNil,
Status: SpanStatusOk,
}
span := GenerateSpan(traceID, parentID, "get_test_info", spanInputs, random)
assert.Equal(t, traceID, span.TraceId)
assert.Equal(t, parentID, span.ParentSpanId)
assert.Equal(t, 8, len(span.Attributes))
assert.Equal(t, otlptrace.Status_Ok, span.Status.Code)
}
func TestGenerateSpans(t *testing.T) {
random := rand.Reader
count1 := 16
spans, nextPos, err := GenerateSpans(count1, 0, "testdata/generated_pict_pairs_spans.txt", random)
assert.Nil(t, err)
assert.Equal(t, count1, len(spans))
count2 := 256
spans, nextPos, err = GenerateSpans(count2, nextPos, "testdata/generated_pict_pairs_spans.txt", random)
assert.Nil(t, err)
assert.Equal(t, count2, len(spans))
count3 := 118
spans, _, err = GenerateSpans(count3, nextPos, "testdata/generated_pict_pairs_spans.txt", random)
assert.Nil(t, err)
assert.Equal(t, count3, len(spans))
}

View File

@ -0,0 +1,307 @@
Parent Tracestate Kind Attributes Events Links Status
Child One Consumer FaaSDatasource Empty Nil AlreadyExists
Child Empty Unspecified gRPCClient Two One ResourceExhausted
Child Four Client gRPCClient Eight Eight DataLoss
Root Four Server FaaSHTTP One Empty ResourceExhausted
Child One Server FaaSOther Nil Two Unimplemented
Child One Unspecified HTTPClient Nil Eight InternalError
Root One Producer FaaSPubSub Two Empty Cancelled
Child One Client DatabaseSQL One One PermissionDenied
Child Four Unspecified FaaSTimer Empty Two FailedPrecondition
Child Empty Unspecified MessagingConsumer Eight Nil InvalidArgument
Root Empty Server FaaSTimer Two Eight AlreadyExists
Child One Internal Nil Eight Two ResourceExhausted
Child Empty Unspecified FaaSHTTP Nil Nil DeadlineExceeded
Child Empty Producer MessagingProducer Empty Empty Ok
Root Four Server HTTPServer Nil One Ok
Root Four Producer Empty One Nil OutOfRange
Child Empty Consumer FaaSDatasource One Two Unavailable
Child One Client gRPCClient Nil Empty OutOfRange
Child Empty Internal Internal One Eight FailedPrecondition
Root Empty Server FaaSTimer Eight One OutOfRange
Child Four Consumer FaaSDatasource Empty One Unauthenticated
Child Empty Client HTTPClient Two Nil DataLoss
Child Empty Unspecified FaaSPubSub Empty Two UnknownError
Child Four Client gRPCClient Two Two Ok
Child Four Unspecified HTTPClient Eight Empty Ok
Root One Server FaaSHTTP Empty Eight Aborted
Child One Client DatabaseNoSQL Nil One FailedPrecondition
Child Empty Client HTTPClient Empty One ResourceExhausted
Child Four Internal Nil Nil Empty AlreadyExists
Root Four Producer FaaSPubSub Eight One AlreadyExists
Child Four Client HTTPClient One Two InvalidArgument
Root One Server FaaSTimer Nil Nil UnknownError
Child Empty Unspecified HTTPServer One Two Cancelled
Child Four Server FaaSHTTP Eight One Cancelled
Child Empty Server FaaSTimer Nil Eight ResourceExhausted
Root One Server gRPCServer Nil Eight InvalidArgument
Child Four Unspecified gRPCServer Two Two Nil
Child One Consumer MessagingConsumer Nil Eight ResourceExhausted
Child One Unspecified MessagingProducer Two Nil FailedPrecondition
Child Four Consumer MessagingConsumer Two Empty Unavailable
Child One Producer FaaSPubSub One Nil Ok
Root Four Server MaxCount Empty Nil Cancelled
Root One Server HTTPServer Empty Eight DeadlineExceeded
Child One Consumer MessagingConsumer Empty Two FailedPrecondition
Child Empty Unspecified MaxCount Two One InvalidArgument
Child One Unspecified FaaSHTTP Two Two OutOfRange
Child Four Unspecified DatabaseSQL Eight Two Aborted
Child One Unspecified MaxCount Eight Eight UnknownError
Child Four Unspecified FaaSOther Eight Empty FailedPrecondition
Root One Server HTTPServer Eight Nil Unavailable
Root Empty Server MaxCount Nil Two Ok
Child Empty Consumer MessagingConsumer One One Aborted
Child One Client Empty Eight One Nil
Root Four Producer MessagingProducer Eight Eight PermissionDenied
Child Empty Internal Nil Empty Nil Nil
Child Empty Unspecified DatabaseNoSQL Two Two NotFound
Child Empty Client DatabaseSQL Nil Empty Nil
Child Four Producer FaaSPubSub Nil Eight ResourceExhausted
Child Empty Unspecified FaaSOther Two One DeadlineExceeded
Child Four Consumer FaaSDatasource Eight Empty InternalError
Root Empty Producer Empty Two Two ResourceExhausted
Root Four Server FaaSOther One Eight Nil
Child Four Internal Internal Two Nil PermissionDenied
Child One Client DatabaseSQL Empty Eight FailedPrecondition
Child Four Producer MessagingProducer One One InvalidArgument
Child Four Unspecified DatabaseNoSQL Empty Empty InvalidArgument
Child Four Unspecified DatabaseNoSQL One Nil ResourceExhausted
Child Empty Producer MessagingProducer Nil Nil Aborted
Child Empty Server gRPCServer Empty Empty Aborted
Child One Unspecified DatabaseNoSQL Eight One DataLoss
Root One Producer MessagingProducer Nil Two DataLoss
Root Four Producer FaaSPubSub Empty One FailedPrecondition
Child Four Client DatabaseNoSQL Empty Eight Unavailable
Child Four Consumer Nil One One NotFound
Root One Server Nil Two Eight DataLoss
Child Four Internal Internal Nil One UnknownError
Child One Producer FaaSPubSub Nil One Unavailable
Child Four Client DatabaseNoSQL Two Empty Unimplemented
Child One Unspecified FaaSOther Empty Empty UnknownError
Child One Client gRPCClient Empty Nil Nil
Child One Unspecified Internal Eight Two Nil
Child Four Unspecified FaaSDatasource Two Eight Ok
Child One Unspecified Empty Nil Empty Ok
Child One Consumer FaaSDatasource Empty Eight OutOfRange
Child Empty Consumer MessagingConsumer Eight One Unimplemented
Child Empty Unspecified Nil One Eight Unimplemented
Child Four Client gRPCClient One Nil Unimplemented
Child Empty Unspecified DatabaseSQL Two Nil Ok
Child One Client DatabaseNoSQL Nil Eight Unauthenticated
Child Four Internal Internal One Empty DeadlineExceeded
Child One Unspecified gRPCServer One Nil OutOfRange
Child Empty Unspecified MaxCount One Two AlreadyExists
Root Empty Server FaaSOther Nil Empty PermissionDenied
Child Four Internal Internal Empty Two InvalidArgument
Root Four Producer MessagingProducer Eight Two DeadlineExceeded
Root One Server FaaSOther Eight Nil NotFound
Child Empty Unspecified Nil Two One Unavailable
Child Four Internal Internal Nil Eight Ok
Child Four Producer Empty Empty Eight FailedPrecondition
Child One Server gRPCServer Eight One DeadlineExceeded
Child Four Consumer MessagingConsumer Two Nil Nil
Root Four Server gRPCServer Eight Two FailedPrecondition
Root Four Producer Empty Empty Nil Unavailable
Root Empty Server HTTPServer Two Empty Unauthenticated
Child Empty Unspecified FaaSHTTP One Empty DataLoss
Child Four Client DatabaseNoSQL One Nil DeadlineExceeded
Root One Producer FaaSPubSub Empty Nil Unimplemented
Root Empty Producer MessagingProducer One One InternalError
Child Empty Unspecified FaaSOther Two Empty AlreadyExists
Child Empty Unspecified DatabaseSQL Empty Nil ResourceExhausted
Child Four Unspecified gRPCClient Eight Nil Unauthenticated
Child Four Client HTTPClient Two Nil UnknownError
Child Four Unspecified HTTPServer Empty Two PermissionDenied
Root Four Producer MessagingProducer One Two AlreadyExists
Child One Unspecified HTTPClient Eight Two PermissionDenied
Child Four Consumer Nil Nil Two Ok
Child Empty Internal Internal Nil Empty NotFound
Child Four Unspecified FaaSDatasource Nil Two FailedPrecondition
Root One Server MaxCount Empty Empty InternalError
Child One Consumer Nil One Eight InvalidArgument
Child One Unspecified HTTPClient Empty Nil OutOfRange
Child Four Client HTTPClient Empty One DeadlineExceeded
Child Empty Client DatabaseSQL Nil Eight Cancelled
Child Four Internal Internal Nil Two Cancelled
Child Four Consumer MessagingConsumer Two Nil InternalError
Child Empty Consumer MessagingConsumer Eight Nil OutOfRange
Root Four Producer MessagingProducer Empty Two Unimplemented
Root One Server FaaSTimer One Empty InvalidArgument
Child Empty Client Empty Empty Eight NotFound
Child Four Unspecified FaaSOther Two Two InternalError
Child One Client DatabaseNoSQL One One Ok
Child One Unspecified MessagingConsumer One Empty Ok
Child Four Unspecified FaaSHTTP Two Empty NotFound
Root Empty Server FaaSTimer Empty Eight Unimplemented
Child One Unspecified FaaSPubSub Nil Nil PermissionDenied
Root Empty Server HTTPServer Eight Two InvalidArgument
Child Four Client HTTPClient One Two Unauthenticated
Child Empty Server gRPCServer One Nil InternalError
Root Empty Producer MessagingProducer Empty Eight OutOfRange
Child Four Producer MessagingProducer Eight Nil Nil
Child Empty Consumer FaaSDatasource Eight Empty Unimplemented
Child Empty Unspecified FaaSPubSub Empty Eight DataLoss
Child Four Unspecified MessagingConsumer Empty Empty AlreadyExists
Child Empty Producer FaaSPubSub One One NotFound
Child One Internal Internal Two Nil InternalError
Root Four Server FaaSTimer Nil One NotFound
Child Four Unspecified FaaSOther Nil One Unavailable
Child Empty Unspecified FaaSHTTP One Nil InternalError
Child Empty Unspecified gRPCServer Eight Nil AlreadyExists
Child One Client HTTPClient Nil One Unimplemented
Child One Client HTTPClient Empty Eight NotFound
Child Four Consumer FaaSDatasource One Eight UnknownError
Root Empty Producer MessagingProducer Two Two Unauthenticated
Child Empty Unspecified FaaSDatasource Two One Aborted
Child One Consumer MessagingConsumer Empty Nil DataLoss
Child One Consumer MessagingConsumer Eight One Cancelled
Child Empty Unspecified FaaSDatasource One Two DataLoss
Child Empty Client gRPCClient Empty Eight FailedPrecondition
Child Empty Unspecified Internal Eight Two ResourceExhausted
Child Empty Client gRPCClient One Nil InternalError
Child Empty Consumer Nil Two Nil PermissionDenied
Child Empty Producer FaaSPubSub One Eight OutOfRange
Child One Unspecified gRPCServer One Nil Ok
Child One Consumer FaaSDatasource One Empty DeadlineExceeded
Child One Unspecified FaaSDatasource Nil Eight NotFound
Child Empty Unspecified DatabaseNoSQL Empty Two PermissionDenied
Child One Unspecified FaaSHTTP Empty Empty UnknownError
Child Empty Server HTTPServer Empty One Aborted
Child Empty Unspecified HTTPClient Eight Eight Cancelled
Child Four Producer MessagingProducer One Empty Cancelled
Child Four Server MaxCount One Eight FailedPrecondition
Child Empty Internal Nil One Eight OutOfRange
Child One Unspecified gRPCServer Empty Two Cancelled
Child Four Server HTTPServer Nil Empty AlreadyExists
Child Four Unspecified Empty Two Two InvalidArgument
Root Empty Server HTTPServer Eight Two DataLoss
Child Empty Client gRPCClient Two Two Unavailable
Child Four Unspecified HTTPServer One One Nil
Child One Client gRPCClient Nil Eight DeadlineExceeded
Root One Server FaaSTimer Empty Eight Cancelled
Child Empty Consumer Nil Eight Eight Cancelled
Child Four Server FaaSTimer Eight Nil Ok
Root One Producer Empty Eight Empty UnknownError
Child One Client Empty Eight Nil AlreadyExists
Child Empty Internal Nil Eight Nil Unauthenticated
Child One Internal Nil Nil Eight DeadlineExceeded
Child One Producer Empty Two Two Cancelled
Child One Unspecified FaaSHTTP Eight Nil InvalidArgument
Child Empty Unspecified HTTPClient One One FailedPrecondition
Child One Unspecified HTTPServer Nil Empty ResourceExhausted
Child One Server Nil One Eight InternalError
Child Four Unspecified Empty Eight Nil Unauthenticated
Child Empty Unspecified MessagingConsumer Eight Two NotFound
Child Four Unspecified MaxCount Empty Eight NotFound
Child One Client gRPCClient One Two InvalidArgument
Child Four Unspecified DatabaseSQL Nil Empty InvalidArgument
Child Four Unspecified FaaSOther One Two OutOfRange
Child Empty Unspecified HTTPServer Two Nil FailedPrecondition
Child Empty Consumer FaaSDatasource Two Eight Nil
Child One Server FaaSTimer Nil One Aborted
Child Four Unspecified DatabaseNoSQL Two Empty UnknownError
Child Empty Server MaxCount Nil Nil OutOfRange
Child Four Unspecified FaaSTimer Nil Nil Unavailable
Child One Unspecified FaaSHTTP Eight Eight AlreadyExists
Child Empty Client DatabaseSQL Empty Eight UnknownError
Child One Producer Empty Eight Nil DeadlineExceeded
Child Empty Producer FaaSPubSub Empty One InternalError
Child Empty Unspecified gRPCClient Two One PermissionDenied
Child One Unspecified DatabaseSQL One Eight Unauthenticated
Child Four Client gRPCClient One Empty Cancelled
Child One Server MaxCount Empty Two Unimplemented
Child Empty Server Nil One Eight UnknownError
Root One Server gRPCServer Eight Eight DataLoss
Child Four Unspecified FaaSPubSub Two One Nil
Root One Server gRPCServer Nil Eight Unimplemented
Child One Server FaaSTimer Two Two Nil
Child Four Unspecified gRPCServer Two Eight Unauthenticated
Child Empty Server FaaSOther One Eight Unauthenticated
Child One Unspecified FaaSDatasource One Eight PermissionDenied
Child Empty Server Nil Two Two FailedPrecondition
Child One Unspecified Empty One Nil PermissionDenied
Child Four Internal Internal One Two Unimplemented
Child Empty Unspecified Empty Eight Two DataLoss
Child Empty Unspecified FaaSTimer Two Empty DeadlineExceeded
Child Empty Unspecified FaaSOther One Eight Aborted
Child One Unspecified FaaSOther One Nil ResourceExhausted
Child Empty Unspecified gRPCServer Two Nil PermissionDenied
Child Empty Unspecified MaxCount Eight Eight Aborted
Child One Consumer MessagingConsumer Two Nil Unauthenticated
Child Four Client Empty One One Unimplemented
Child Four Server MaxCount Two Eight PermissionDenied
Child One Unspecified FaaSDatasource Nil Nil ResourceExhausted
Child Empty Unspecified gRPCServer Eight Empty Unavailable
Child One Unspecified HTTPServer Nil One UnknownError
Child Four Internal Internal Nil Eight OutOfRange
Child One Unspecified FaaSOther One Nil Ok
Child Four Client DatabaseSQL Eight Two InternalError
Child Empty Unspecified DatabaseSQL One Eight NotFound
Child Empty Client DatabaseSQL One Nil OutOfRange
Child Four Server FaaSTimer Eight Empty Unauthenticated
Child Four Client DatabaseSQL One Nil AlreadyExists
Child Empty Unspecified HTTPServer Empty One InternalError
Root One Server MaxCount One One Nil
Child Four Unspecified MessagingProducer Two Nil ResourceExhausted
Child Four Client HTTPClient One Two Aborted
Child Empty Client DatabaseNoSQL Two Nil AlreadyExists
Child One Unspecified MaxCount Nil Empty DataLoss
Child One Internal Internal Empty Nil DataLoss
Child One Producer MessagingProducer One Two NotFound
Child One Unspecified FaaSTimer Two Two PermissionDenied
Root One Server FaaSOther Eight Empty Cancelled
Child Empty Client DatabaseSQL Empty One DeadlineExceeded
Child One Unspecified HTTPServer Two Eight Unimplemented
Child Four Client HTTPClient Nil Eight Nil
Root Empty Server MaxCount Nil Nil Unavailable
Child Four Internal Internal One One Aborted
Child One Unspecified FaaSHTTP Empty Nil PermissionDenied
Child One Unspecified FaaSHTTP Nil Two Unimplemented
Child One Unspecified MessagingConsumer Two Two PermissionDenied
Root One Server FaaSOther Nil Nil InvalidArgument
Child Empty Unspecified HTTPClient Empty Eight Unavailable
Child One Unspecified FaaSPubSub Eight Empty Unauthenticated
Child Empty Client gRPCClient Empty Empty AlreadyExists
Child One Unspecified DatabaseNoSQL One Empty InternalError
Root One Server FaaSHTTP One Empty Unauthenticated
Child Empty Server MaxCount Empty Empty ResourceExhausted
Child Four Client DatabaseSQL One Nil Unavailable
Root Four Server gRPCServer Nil Eight ResourceExhausted
Child Empty Internal Internal Nil Empty Unauthenticated
Child Four Unspecified HTTPServer Two Empty NotFound
Child Four Server MaxCount Two Eight Unauthenticated
Child Empty Unspecified MessagingConsumer Empty Two DeadlineExceeded
Child Four Client HTTPClient Two Two AlreadyExists
Child One Unspecified gRPCClient Nil Two NotFound
Child Empty Unspecified FaaSPubSub Nil Nil InvalidArgument
Child One Internal Internal Two Two AlreadyExists
Child Empty Consumer FaaSDatasource One Two InvalidArgument
Child Empty Server FaaSOther Nil Eight DataLoss
Child One Unspecified gRPCClient Nil Empty UnknownError
Child One Server Nil One Empty Aborted
Child Four Unspecified FaaSTimer One Two DataLoss
Child Empty Unspecified FaaSPubSub Empty One Aborted
Child One Unspecified FaaSHTTP Eight One Nil
Child One Client DatabaseSQL Eight Nil DataLoss
Child Empty Server HTTPServer Nil Eight OutOfRange
Child One Client gRPCClient Eight Two Aborted
Child One Unspecified DatabaseNoSQL Two Eight Nil
Child Four Client DatabaseNoSQL Eight Empty Aborted
Child Empty Internal Internal Eight One Unavailable
Child One Unspecified gRPCServer One Eight NotFound
Child Empty Unspecified FaaSHTTP One Two Ok
Child Four Unspecified gRPCServer One Empty UnknownError
Child Four Client DatabaseNoSQL One Nil Cancelled
Child Four Unspecified MessagingProducer Two Empty Unavailable
Child Empty Unspecified Empty Nil Eight Aborted
Child Four Server MaxCount Nil Nil DeadlineExceeded
Child Empty Client DatabaseSQL One Nil Unimplemented
Child Four Unspecified FaaSTimer Two Empty InternalError
Child Empty Unspecified DatabaseNoSQL One Eight OutOfRange
Root One Server FaaSHTTP Empty Empty Unavailable
Child One Unspecified FaaSDatasource Two Empty Cancelled
Child Empty Consumer MessagingConsumer Two One UnknownError
Child Empty Unspecified FaaSHTTP Two One FailedPrecondition
Child One Client Empty Two Nil InternalError
Root One Producer FaaSPubSub Eight Two DeadlineExceeded
Root One Producer MessagingProducer Empty Two UnknownError

View File

@ -0,0 +1,29 @@
Resource InstrumentationLibrary Spans
Nil None Several
Nil One One
Empty One None
K8sCloud None All
VMOnPrem Two All
Faas Two None
K8sOnPrem One Several
K8sOnPrem Two All
VMOnPrem None One
Faas One All
K8sCloud Two Several
Nil None None
K8sOnPrem None None
Faas None One
VMCloud One None
VMCloud Two All
Nil Two All
K8sCloud One None
K8sCloud Two One
VMCloud None One
Empty Two One
Faas One Several
VMOnPrem One None
K8sOnPrem One One
VMCloud None Several
Empty None All
Empty None Several
VMOnPrem Two Several

View File

@ -0,0 +1,14 @@
Parent: Root, Child
Tracestate: Empty, One, Four
Kind: Unspecified, Internal, Server, Client, Producer, Consumer
Attributes: Nil, Empty, DatabaseSQL, DatabaseNoSQL, FaaSDatasource, FaaSHTTP, FaaSPubSub, FaaSTimer, FaaSOther, HTTPClient, HTTPServer, MessagingProducer, MessagingConsumer, gRPCClient, gRPCServer, Internal, MaxCount
Events: Nil, Empty, One, Two, Eight
Links: Nil, Empty, One, Two, Eight
Status: Nil, Ok, Cancelled, UnknownError, InvalidArgument, DeadlineExceeded, NotFound, AlreadyExists, PermissionDenied, ResourceExhausted, FailedPrecondition, Aborted, OutOfRange, Unimplemented, InternalError, Unavailable, DataLoss, Unauthenticated
IF [Parent] = "Root" THEN [Kind] in {"Server", "Producer"};
IF [Kind] = "Internal" THEN [Attributes] in {"Nil", "Internal"};
IF [Kind] = "Server" THEN [Attributes] in {"Nil", "FaaSHTTP", "FaaSTimer", "FaaSOther", "HTTPServer", "gRPCServer", "MaxCount"};
IF [Kind] = "Client" THEN [Attributes] in {"Empty", "DatabaseSQL", "DatabaseNoSQL", "HTTPClient", "gRPCClient"};
IF [Kind] = "Producer" THEN [Attributes] in {"Empty", "MessagingProducer", "FaaSPubSub"};
IF [Kind] = "Consumer" THEN [Attributes] in {"Nil", "MessagingConsumer", "FaaSDatasource"};

View File

@ -0,0 +1,3 @@
Resource: Nil, Empty, VMOnPrem, VMCloud, K8sOnPrem, K8sCloud, Faas
InstrumentationLibrary: None, One, Two
Spans: None, One, Several, All

View File

@ -0,0 +1,139 @@
// Copyright 2020, 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 goldendataset
import (
"fmt"
"io"
otlpcommon "github.com/open-telemetry/opentelemetry-proto/gen/go/common/v1"
otlptrace "github.com/open-telemetry/opentelemetry-proto/gen/go/trace/v1"
)
//GenerateResourceSpans generates a slice of OTLP ResourceSpans objects based on the PICT-generated pairwise
//parameters defined in the parameters file specified by the tracePairsFile parameter. The pairs to generate
//spans for for defined in the file specified by the spanPairsFile parameter. The random parameter injects the
//random number generator to use in generating IDs and other random values.
//The slice of ResourceSpans are returned. If an err is returned, the slice elements will be nil.
func GenerateResourceSpans(tracePairsFile string, spanPairsFile string,
random io.Reader) ([]*otlptrace.ResourceSpans, error) {
pairsData, err := loadPictOutputFile(tracePairsFile)
if err != nil {
return nil, err
}
pairsTotal := len(pairsData) - 1
spans := make([]*otlptrace.ResourceSpans, pairsTotal)
for index, values := range pairsData {
if index == 0 {
continue
}
tracingInputs := &PICTTracingInputs{
Resource: PICTInputResource(values[TracesColumnResource]),
InstrumentationLibrary: PICTInputInstrumentationLibrary(values[TracesColumnInstrumentationLibrary]),
Spans: PICTInputSpans(values[TracesColumnSpans]),
}
rscSpan, spanErr := GenerateResourceSpan(tracingInputs, spanPairsFile, random)
if spanErr != nil {
err = spanErr
}
spans[index-1] = rscSpan
}
return spans, err
}
//GenerateResourceSpan generates a single OTLP ResourceSpans populated based on the provided inputs. They are:
// tracingInputs - the pairwise combination of field value variations for this ResourceSpans
// spanPairsFile - the file with the PICT-generated parameter combinations to generate spans for
// random - the random number generator to use in generating ID values
//
//The generated resource spans. If err is not nil, some or all of the resource spans fields will be nil.
func GenerateResourceSpan(tracingInputs *PICTTracingInputs, spanPairsFile string,
random io.Reader) (*otlptrace.ResourceSpans, error) {
libSpans, err := generateLibrarySpansArray(tracingInputs, spanPairsFile, random)
return &otlptrace.ResourceSpans{
Resource: GenerateResource(tracingInputs.Resource),
InstrumentationLibrarySpans: libSpans,
}, err
}
func generateLibrarySpansArray(tracingInputs *PICTTracingInputs, spanPairsFile string,
random io.Reader) ([]*otlptrace.InstrumentationLibrarySpans, error) {
var count int
switch tracingInputs.InstrumentationLibrary {
case LibraryNone:
count = 1
case LibraryOne:
count = 1
case LibraryTwo:
count = 2
}
var err error
libSpans := make([]*otlptrace.InstrumentationLibrarySpans, count)
for i := 0; i < count; i++ {
libSpans[i], err = generateLibrarySpans(tracingInputs, i, spanPairsFile, random)
}
return libSpans, err
}
func generateLibrarySpans(tracingInputs *PICTTracingInputs, index int, spanPairsFile string,
random io.Reader) (*otlptrace.InstrumentationLibrarySpans, error) {
spanCaseCount, err := countTotalSpanCases(spanPairsFile)
if err != nil {
return nil, err
}
var spans []*otlptrace.Span
switch tracingInputs.Spans {
case LibrarySpansNone:
spans = make([]*otlptrace.Span, 0)
case LibrarySpansOne:
spans, _, err = GenerateSpans(1, 0, spanPairsFile, random)
case LibrarySpansSeveral:
spans, _, err = GenerateSpans(spanCaseCount/4, 0, spanPairsFile, random)
case LibrarySpansAll:
spans, _, err = GenerateSpans(spanCaseCount, 0, spanPairsFile, random)
default:
spans, _, err = GenerateSpans(16, 0, spanPairsFile, random)
}
return &otlptrace.InstrumentationLibrarySpans{
InstrumentationLibrary: generateInstrumentationLibrary(tracingInputs, index),
Spans: spans,
}, err
}
func countTotalSpanCases(spanPairsFile string) (int, error) {
pairsData, err := loadPictOutputFile(spanPairsFile)
if err != nil {
return 0, err
}
count := len(pairsData) - 1
return count, err
}
func generateInstrumentationLibrary(tracingInputs *PICTTracingInputs,
index int) *otlpcommon.InstrumentationLibrary {
if LibraryNone == tracingInputs.InstrumentationLibrary {
return nil
}
nameStr := fmt.Sprintf("%s-%s-%s-%d", tracingInputs.Resource, tracingInputs.InstrumentationLibrary,
tracingInputs.Spans, index)
verStr := "semver:1.1.7"
if index > 0 {
verStr = ""
}
return &otlpcommon.InstrumentationLibrary{
Name: nameStr,
Version: verStr,
}
}

View File

@ -0,0 +1,31 @@
// Copyright 2020, 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 goldendataset
import (
"io"
"math/rand"
"testing"
"github.com/stretchr/testify/assert"
)
func TestGenerateTraces(t *testing.T) {
random := io.Reader(rand.New(rand.NewSource(42)))
rscSpans, err := GenerateResourceSpans("testdata/generated_pict_pairs_traces.txt",
"testdata/generated_pict_pairs_spans.txt", random)
assert.Nil(t, err)
assert.Equal(t, 28, len(rscSpans))
}

View File

@ -15,18 +15,22 @@
package conventions
// OpenTelemetry Semantic Convention values for Resource attribute names.
// See: https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/data-resource-semantic-conventions.md
// See: https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/resource/semantic_conventions/README.md
const (
AttributeServiceName = "service.name"
AttributeServiceNamespace = "service.namespace"
AttributeServiceInstance = "service.instance.id"
AttributeServiceVersion = "service.version"
AttributeLibraryName = "library.name"
AttributeLibraryLanguage = "library.language"
AttributeLibraryVersion = "library.version"
AttributeTelemetrySDKName = "telemetry.sdk.name"
AttributeTelemetrySDKLanguage = "telemetry.sdk.language"
AttributeTelemetrySDKVersion = "telemetry.sdk.version"
AttributeContainerName = "container.name"
AttributeContainerImage = "container.image.name"
AttributeContainerTag = "container.image.tag"
AttributeFaasName = "faas.name"
AttributeFaasID = "faas.id"
AttributeFaasVersion = "faas.version"
AttributeFaasInstance = "faas.instance"
AttributeK8sCluster = "k8s.cluster.name"
AttributeK8sNamespace = "k8s.namespace.name"
AttributeK8sPod = "k8s.pod.name"
@ -42,13 +46,10 @@ const (
AttributeCloudAccount = "cloud.account.id"
AttributeCloudRegion = "cloud.region"
AttributeCloudZone = "cloud.zone"
AttributeTelemetrySDKName = "telemetry.sdk.name"
AttributeTelemetrySDKLanguage = "telemetry.sdk.language"
AttributeTelemetrySDKVersion = "telemetry.sdk.version"
)
// OpenTelemetry Semantic Convention values for general Span attribute names.
// See: https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/data-span-general.md
// See: https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/trace/semantic_conventions/span-general.md
const (
AttributeComponent = "component"
AttributeNetTransport = "net.transport"
@ -71,7 +72,7 @@ const (
)
// OpenTelemetry Semantic Convention attribute names for HTTP related attributes
// See: https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/data-http.md
// See: https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/trace/semantic_conventions/http.md
const (
AttributeHTTPMethod = "http.method"
AttributeHTTPURL = "http.url"
@ -90,7 +91,7 @@ const (
)
// OpenTelemetry Semantic Convention attribute names for database related attributes
// See: https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/data-database.md
// See: https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/trace/semantic_conventions/database.md
const (
AttributeDBType = "db.type"
AttributeDBInstance = "db.instance"
@ -100,7 +101,7 @@ const (
)
// OpenTelemetry Semantic Convention attribute names for gRPC related attributes
// See: https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/data-rpc.md
// See: https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/trace/semantic_conventions/rpc.md
const (
AttributeRPCService = "rpc.service"
EventTypeMessage = "message"
@ -111,3 +112,38 @@ const (
AttributeMessageCompressedSize = "message.compressed_size"
AttributeMessageUncompressedSize = "message.uncompressed_size"
)
// OpenTelemetry Semantic Convention attribute names for FaaS related attributes
// See: https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/trace/semantic_conventions/faas.md
const (
AttributeFaaSTrigger = "faas.trigger"
AttributeFaaSExecution = "faas.execution"
AttributeFaaSDocumentCollection = "faas.document.collection"
AttributeFaaSDocumentOperation = "faas.document.operation"
AttributeFaaSDocumentTime = "faas.document.time"
AttributeFaaSDocumentName = "faas.document.name"
AttributeFaaSTime = "faas.time"
AttributeFaaSCron = "faas.cron"
FaaSTriggerDataSource = "datasource"
FaaSTriggerHTTP = "http"
FaaSTriggerPubSub = "pubsub"
FaaSTriggerTimer = "timer"
FaaSTriggerOther = "other"
)
// OpenTelemetry Semantic Convention attribute names for messaging system related attributes
// See: https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/trace/semantic_conventions/messaging.md
const (
AttributeMessagingSystem = "messaging.system"
AttributeMessagingDestination = "messaging.destination"
AttributeMessagingDestinationKind = "messaging.destination_kind"
AttributeMessagingTempDestination = "messaging.temp_destination"
AttributeMessagingProtocol = "messaging.protocol"
AttributeMessagingProtocolVersion = "messaging.protocol_version"
AttributeMessagingURL = "messaging.url"
AttributeMessagingMessageID = "messaging.message_id"
AttributeMessagingConversationID = "messaging.conversation_id"
AttributeMessagingPayloadSize = "messaging.message_payload_size_bytes"
AttributeMessagingPayloadCompressedSize = "messaging.message_payload_compressed_size_bytes"
AttributeMessagingOperation = "messaging.operation"
)

View File

@ -38,8 +38,8 @@ func TestMetricsDataToOC(t *testing.T) {
attrs.Upsert(conventions.AttributeHostHostname, pdata.NewAttributeValueString("host1"))
attrs.Upsert(conventions.OCAttributeProcessID, pdata.NewAttributeValueInt(123))
attrs.Upsert(conventions.OCAttributeProcessStartTime, pdata.NewAttributeValueString("2020-02-11T20:26:00Z"))
attrs.Upsert(conventions.AttributeLibraryLanguage, pdata.NewAttributeValueString("CPP"))
attrs.Upsert(conventions.AttributeLibraryVersion, pdata.NewAttributeValueString("v2.0.1"))
attrs.Upsert(conventions.AttributeTelemetrySDKLanguage, pdata.NewAttributeValueString("CPP"))
attrs.Upsert(conventions.AttributeTelemetrySDKVersion, pdata.NewAttributeValueString("v2.0.1"))
attrs.Upsert(conventions.OCAttributeExporterVersion, pdata.NewAttributeValueString("v1.2.0"))
tests := []struct {

View File

@ -492,16 +492,16 @@ func generateResourceWithOcNodeAndResource() pdata.Resource {
resource := pdata.NewResource()
resource.InitEmpty()
resource.Attributes().InitFromMap(map[string]pdata.AttributeValue{
conventions.OCAttributeProcessStartTime: pdata.NewAttributeValueString("2020-02-11T20:26:00Z"),
conventions.AttributeHostHostname: pdata.NewAttributeValueString("host1"),
conventions.OCAttributeProcessID: pdata.NewAttributeValueInt(123),
conventions.AttributeLibraryVersion: pdata.NewAttributeValueString("v2.0.1"),
conventions.OCAttributeExporterVersion: pdata.NewAttributeValueString("v1.2.0"),
conventions.AttributeLibraryLanguage: pdata.NewAttributeValueString("CPP"),
conventions.OCAttributeResourceType: pdata.NewAttributeValueString("good-resource"),
"node-str-attr": pdata.NewAttributeValueString("node-str-attr-val"),
"resource-str-attr": pdata.NewAttributeValueString("resource-str-attr-val"),
"resource-int-attr": pdata.NewAttributeValueInt(123),
conventions.OCAttributeProcessStartTime: pdata.NewAttributeValueString("2020-02-11T20:26:00Z"),
conventions.AttributeHostHostname: pdata.NewAttributeValueString("host1"),
conventions.OCAttributeProcessID: pdata.NewAttributeValueInt(123),
conventions.AttributeTelemetrySDKVersion: pdata.NewAttributeValueString("v2.0.1"),
conventions.OCAttributeExporterVersion: pdata.NewAttributeValueString("v1.2.0"),
conventions.AttributeTelemetrySDKLanguage: pdata.NewAttributeValueString("CPP"),
conventions.OCAttributeResourceType: pdata.NewAttributeValueString("good-resource"),
"node-str-attr": pdata.NewAttributeValueString("node-str-attr-val"),
"resource-str-attr": pdata.NewAttributeValueString("resource-str-attr-val"),
"resource-int-attr": pdata.NewAttributeValueInt(123),
})
return resource
}

View File

@ -90,13 +90,13 @@ func ocNodeResourceToInternal(ocNode *occommon.Node, ocResource *ocresource.Reso
}
if ocNode.LibraryInfo != nil {
if ocNode.LibraryInfo.CoreLibraryVersion != "" {
attrs.UpsertString(conventions.AttributeLibraryVersion, ocNode.LibraryInfo.CoreLibraryVersion)
attrs.UpsertString(conventions.AttributeTelemetrySDKVersion, ocNode.LibraryInfo.CoreLibraryVersion)
}
if ocNode.LibraryInfo.ExporterVersion != "" {
attrs.UpsertString(conventions.OCAttributeExporterVersion, ocNode.LibraryInfo.ExporterVersion)
}
if ocNode.LibraryInfo.Language != occommon.LibraryInfo_LANGUAGE_UNSPECIFIED {
attrs.UpsertString(conventions.AttributeLibraryLanguage, ocNode.LibraryInfo.Language.String())
attrs.UpsertString(conventions.AttributeTelemetrySDKLanguage, ocNode.LibraryInfo.Language.String())
}
}
}

View File

@ -79,7 +79,7 @@ func internalResourceToOC(resource pdata.Resource) (*occommon.Node, *ocresource.
ocNode.Identifier = &occommon.ProcessIdentifier{}
}
ocNode.Identifier.Pid = uint32(pid)
case conventions.AttributeLibraryVersion:
case conventions.AttributeTelemetrySDKVersion:
if ocNode.LibraryInfo == nil {
ocNode.LibraryInfo = &occommon.LibraryInfo{}
}
@ -89,7 +89,7 @@ func internalResourceToOC(resource pdata.Resource) (*occommon.Node, *ocresource.
ocNode.LibraryInfo = &occommon.LibraryInfo{}
}
ocNode.LibraryInfo.ExporterVersion = val
case conventions.AttributeLibraryLanguage:
case conventions.AttributeTelemetrySDKLanguage:
if code, ok := occommon.LibraryInfo_Language_value[val]; ok {
if ocNode.LibraryInfo == nil {
ocNode.LibraryInfo = &occommon.LibraryInfo{}