Skip to content

Commit

Permalink
Merge branch 'main' into jaegerremotesampling_replace_thrift-gen_with…
Browse files Browse the repository at this point in the history
…_proto-gen

Signed-off-by: Benedikt Bongartz <bongartz@klimlive.de>
  • Loading branch information
frzifus committed Aug 31, 2023
2 parents a4f2962 + 3a6f547 commit f99ee72
Show file tree
Hide file tree
Showing 18 changed files with 734 additions and 15 deletions.
20 changes: 20 additions & 0 deletions .chloggen/feat_time-to-int.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Use this changelog template to create an entry for release notes.
# If your change doesn't affect end users, such as a test fix or a tooling change,
# you should instead start your pull request title with [chore] or use the "Skip Changelog" label.

# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
change_type: 'enhancement'

# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver)
component: 'pkg/ottl'

# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
note: "Add converters to convert time to unix nanoseconds, unix microseconds, unix milliseconds or unix seconds"

# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists.
issues: [24686]

# (Optional) One or more lines of additional information to render under the primary note.
# These lines will be padded with 2 spaces and then inserted directly into the document.
# Use pipe (|) for multiline entries.
subtext:
20 changes: 20 additions & 0 deletions .chloggen/fix-tailsampling-lost-instrumentation-scope-info.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Use this changelog template to create an entry for release notes.
# If your change doesn't affect end users, such as a test fix or a tooling change,
# you should instead start your pull request title with [chore] or use the "Skip Changelog" label.

# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
change_type: bug_fix

# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver)
component: processor/tailsampling

# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
note: Added saving instrumentation library information for tail-sampling

# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists.
issues: [13642]

# (Optional) One or more lines of additional information to render under the primary note.
# These lines will be padded with 2 spaces and then inserted directly into the document.
# Use pipe (|) for multiline entries.
subtext:
2 changes: 1 addition & 1 deletion .github/workflows/scripts/add-labels.sh
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ for LABEL_REQ in ${LABELS}; do

# Labels added by a GitHub Actions workflow don't trigger other workflows
# by design, so we have to manually ping code owners here.
COMPONENT="${LABEL}" ISSUE=${ISSUE} SENDER="${SENDER}" bash "${CUR_DIRECTORY}/ping-codeowners.sh"
COMPONENT="${LABEL}" ISSUE=${ISSUE} SENDER="${SENDER}" bash "${CUR_DIRECTORY}/ping-codeowners-issues.sh"
else
gh issue edit "${ISSUE}" --remove-label "${LABEL}"
fi
Expand Down
1 change: 0 additions & 1 deletion cmd/checkapi/allowlist.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ exporter/awscloudwatchlogsexporter
exporter/awskinesisexporter
exporter/azuremonitorexporter
exporter/coralogixexporter
exporter/datasetexporter
exporter/dynatraceexporter
exporter/elasticsearchexporter
exporter/f5cloudexporter
Expand Down
4 changes: 2 additions & 2 deletions exporter/datasetexporter/traces_exporter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ var trace1Id = [16]byte{2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}
var trace2Id = [16]byte{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}
var trace3Id = [16]byte{4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}

func GenerateTracesTreesAndOrphans() ptrace.Traces {
func generateTracesTreesAndOrphans() ptrace.Traces {
td := ptrace.NewTraces()
rs0 := td.ResourceSpans().AppendEmpty()
rs0ils0 := rs0.ScopeSpans().AppendEmpty()
Expand Down Expand Up @@ -434,7 +434,7 @@ func generateSimpleEvent(
}

func TestBuildEventsFromTracesTrees(t *testing.T) {
traces := GenerateTracesTreesAndOrphans()
traces := generateTracesTreesAndOrphans()
was := buildEventsFromTraces(traces, testServerHost)

statusUnset := ptrace.NewStatus()
Expand Down
30 changes: 30 additions & 0 deletions pkg/ottl/expression.go
Original file line number Diff line number Diff line change
Expand Up @@ -583,6 +583,36 @@ func (p *Parser[K]) newGetterFromConverter(c converter) (Getter[K], error) {
}, nil
}

// TimeGetter is a Getter that must return an time.Time.
type TimeGetter[K any] interface {
// Get retrieves an time.Time value.
Get(ctx context.Context, tCtx K) (time.Time, error)
}

// StandardTimeGetter is a basic implementation of IntGetter
type StandardTimeGetter[K any] struct {
Getter func(ctx context.Context, tCtx K) (interface{}, error)
}

// Get retrieves a time.Time value.
// If the value is not a time.Time, a new TypeError is returned.
// If there is an error getting the value it will be returned.
func (g StandardTimeGetter[K]) Get(ctx context.Context, tCtx K) (time.Time, error) {
val, err := g.Getter(ctx, tCtx)
if err != nil {
return time.Time{}, fmt.Errorf("error getting value in %T: %w", g, err)
}
if val == nil {
return time.Time{}, TypeError("expected time but got nil")
}
switch v := val.(type) {
case time.Time:
return v, nil
default:
return time.Time{}, TypeError(fmt.Sprintf("expected time but got %T", val))
}
}

// DurationGetter is a Getter that must return an time.Duration.
type DurationGetter[K any] interface {
// Get retrieves an int64 value.
Expand Down
89 changes: 89 additions & 0 deletions pkg/ottl/expression_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1657,3 +1657,92 @@ func Test_StandardDurationGetter_WrappedError(t *testing.T) {
_, ok := err.(TypeError)
assert.False(t, ok)
}

func Test_StandardTimeGetter(t *testing.T) {
tests := []struct {
name string
getter StandardTimeGetter[interface{}]
want string
valid bool
expectedErrorMsg string
}{
{
name: "2023 time",
getter: StandardTimeGetter[interface{}]{
Getter: func(ctx context.Context, tCtx interface{}) (interface{}, error) {
return time.Date(2023, 8, 17, 1, 1, 1, 1, time.UTC), nil
},
},
want: "2023-08-17T01:01:01.000000001Z",
valid: true,
},
{
name: "before 2000 time",
getter: StandardTimeGetter[interface{}]{
Getter: func(ctx context.Context, tCtx interface{}) (interface{}, error) {
return time.Date(1999, 12, 1, 10, 59, 58, 57, time.UTC), nil
},
},
want: "1999-12-01T10:59:58.000000057Z",
valid: true,
},
{
name: "wrong type - duration",
getter: StandardTimeGetter[interface{}]{
Getter: func(ctx context.Context, tCtx interface{}) (interface{}, error) {
return time.ParseDuration("70ns")
},
},
valid: false,
expectedErrorMsg: "expected time but got time.Duration",
},
{
name: "wrong type - bool",
getter: StandardTimeGetter[interface{}]{
Getter: func(ctx context.Context, tCtx interface{}) (interface{}, error) {
return true, nil
},
},
valid: false,
expectedErrorMsg: "expected time but got bool",
},
{
name: "nil",
getter: StandardTimeGetter[interface{}]{
Getter: func(ctx context.Context, tCtx interface{}) (interface{}, error) {
return nil, nil
},
},
valid: false,
expectedErrorMsg: "expected time but got nil",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
val, err := tt.getter.Get(context.Background(), nil)
if tt.valid {
assert.NoError(t, err)
var want time.Time
want, err = time.Parse("2006-01-02T15:04:05.000000000Z", tt.want)
assert.NoError(t, err)
assert.Equal(t, want, val)
} else {
assert.ErrorContains(t, err, tt.expectedErrorMsg)
}
})
}
}

// nolint:errorlint
func Test_StandardTimeGetter_WrappedError(t *testing.T) {
getter := StandardTimeGetter[interface{}]{
Getter: func(ctx context.Context, tCtx interface{}) (interface{}, error) {
return nil, TypeError("")
},
}
_, err := getter.Get(context.Background(), nil)
assert.Error(t, err)
_, ok := err.(TypeError)
assert.False(t, ok)
}
38 changes: 38 additions & 0 deletions pkg/ottl/ottlfuncs/func_unix_micro.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

package ottlfuncs // import "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/ottlfuncs"

import (
"context"
"fmt"

"github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl"
)

type UnixMicroArguments[K any] struct {
Time ottl.TimeGetter[K] `ottlarg:"0"`
}

func NewUnixMicroFactory[K any]() ottl.Factory[K] {
return ottl.NewFactory("UnixMicro", &UnixMicroArguments[K]{}, createUnixMicroFunction[K])
}
func createUnixMicroFunction[K any](_ ottl.FunctionContext, oArgs ottl.Arguments) (ottl.ExprFunc[K], error) {
args, ok := oArgs.(*UnixMicroArguments[K])

if !ok {
return nil, fmt.Errorf("UnixMicroFactory args must be of type *UnixMicroArguments[K]")
}

return UnixMicro(args.Time)
}

func UnixMicro[K any](inputTime ottl.TimeGetter[K]) (ottl.ExprFunc[K], error) {
return func(ctx context.Context, tCtx K) (interface{}, error) {
t, err := inputTime.Get(ctx, tCtx)
if err != nil {
return nil, err
}
return t.UnixMicro(), nil
}, nil
}
69 changes: 69 additions & 0 deletions pkg/ottl/ottlfuncs/func_unix_micro_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

package ottlfuncs

import (
"context"
"testing"
"time"

"github.com/stretchr/testify/assert"

"github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl"
)

func Test_TimeUnixMicro(t *testing.T) {
tests := []struct {
name string
time ottl.TimeGetter[interface{}]
expected time.Time
}{
{
name: "January 1, 2023",
time: &ottl.StandardTimeGetter[interface{}]{
Getter: func(ctx context.Context, tCtx interface{}) (interface{}, error) {
return time.Date(2023, 1, 1, 0, 0, 0, 0, time.Local), nil
},
},
expected: time.Date(2023, 1, 1, 0, 0, 0, 0, time.Local),
},
{
name: "April 30, 2001, 3pm",
time: &ottl.StandardTimeGetter[interface{}]{
Getter: func(ctx context.Context, tCtx interface{}) (interface{}, error) {
return time.Date(2001, 4, 30, 15, 0, 0, 0, time.Local), nil
},
},
expected: time.Date(2001, 4, 30, 15, 0, 0, 0, time.Local),
},
{
name: "November 12, 1980, 4:35:01am",
time: &ottl.StandardTimeGetter[interface{}]{
Getter: func(ctx context.Context, tCtx interface{}) (interface{}, error) {
return time.Date(1980, 11, 12, 4, 35, 1, 0, time.Local), nil
},
},
expected: time.Date(1980, 11, 12, 4, 35, 1, 0, time.Local),
},
{
name: "October 4, 2020, 5:05 5 microseconds 5 nanosecs",
time: &ottl.StandardTimeGetter[interface{}]{
Getter: func(ctx context.Context, tCtx interface{}) (interface{}, error) {
return time.Date(2020, 10, 4, 5, 5, 5, 5, time.Local), nil
},
},
expected: time.Date(2020, 10, 4, 5, 5, 5, 5, time.Local),
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
exprFunc, err := UnixMicro(tt.time)
assert.NoError(t, err)
result, err := exprFunc(nil, nil)
assert.NoError(t, err)
want := tt.expected.UnixMicro()
assert.Equal(t, want, result)
})
}
}
38 changes: 38 additions & 0 deletions pkg/ottl/ottlfuncs/func_unix_milli.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

package ottlfuncs // import "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/ottlfuncs"

import (
"context"
"fmt"

"github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl"
)

type UnixMilliArguments[K any] struct {
Time ottl.TimeGetter[K] `ottlarg:"0"`
}

func NewUnixMilliFactory[K any]() ottl.Factory[K] {
return ottl.NewFactory("UnixMilli", &UnixMilliArguments[K]{}, createUnixMilliFunction[K])
}
func createUnixMilliFunction[K any](_ ottl.FunctionContext, oArgs ottl.Arguments) (ottl.ExprFunc[K], error) {
args, ok := oArgs.(*UnixMilliArguments[K])

if !ok {
return nil, fmt.Errorf("UnixMilliFactory args must be of type *UnixMilliArguments[K]")
}

return UnixMilli(args.Time)
}

func UnixMilli[K any](inputTime ottl.TimeGetter[K]) (ottl.ExprFunc[K], error) {
return func(ctx context.Context, tCtx K) (interface{}, error) {
t, err := inputTime.Get(ctx, tCtx)
if err != nil {
return nil, err
}
return t.UnixMilli(), nil
}, nil
}
Loading

0 comments on commit f99ee72

Please sign in to comment.