diff --git a/.chloggen/feat_githubgen_skipmembercheck.yaml b/.chloggen/feat_githubgen_skipmembercheck.yaml new file mode 100644 index 000000000000..930836158dfc --- /dev/null +++ b/.chloggen/feat_githubgen_skipmembercheck.yaml @@ -0,0 +1,27 @@ +# Use this changelog template to create an entry for release notes. + +# 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: cmd/githubgen + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Adds a flag to skip checking GitHub organization membership for CODEOWNERS + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +issues: [36263] + +# (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: + +# If your change doesn't affect end users or the exported elements of any package, +# you should instead start your pull request title with [chore] or use the "Skip Changelog" label. +# Optional: The change log or logs in which this entry should be included. +# e.g. '[user]' or '[user, api]' +# Include 'user' if the change is relevant to end users. +# Include 'api' if there is a change to a library API. +# Default: '[user]' +change_logs: [user] diff --git a/.chloggen/span-rpocessor-keep-original-name.yaml b/.chloggen/span-rpocessor-keep-original-name.yaml new file mode 100644 index 000000000000..d3e229b933a5 --- /dev/null +++ b/.chloggen/span-rpocessor-keep-original-name.yaml @@ -0,0 +1,27 @@ +# Use this changelog template to create an entry for release notes. + +# 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: processor/spanprocessor + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: "Add a new configuration option to keep the original span name when extracting attributes from the span name." + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +issues: [36120] + +# (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: + +# If your change doesn't affect end users or the exported elements of any package, +# you should instead start your pull request title with [chore] or use the "Skip Changelog" label. +# Optional: The change log or logs in which this entry should be included. +# e.g. '[user]' or '[user, api]' +# Include 'user' if the change is relevant to end users. +# Include 'api' if there is a change to a library API. +# Default: '[user]' +change_logs: [user] diff --git a/cmd/githubgen/README.md b/cmd/githubgen/README.md index 2703499eba8d..fa81f646815f 100644 --- a/cmd/githubgen/README.md +++ b/cmd/githubgen/README.md @@ -19,7 +19,7 @@ $> GITHUB_TOKEN= githubgen --folder . [--allowlist cmd/githubgen/all ## Checking codeowners against OpenTelemetry membership via Github API -To authenticate, set the environment variable `GITHUB_TOKEN` to a PAT token. +To authenticate, set the environment variable `GITHUB_TOKEN` to a PAT token. If a PAT is not available you can use the `--skipgithub` flag to avoid checking for membership in the GitHub organization. For each codeowner, the script will check if the user is registered as a member of the OpenTelemetry organization. diff --git a/cmd/githubgen/codeowners.go b/cmd/githubgen/codeowners.go index dbe8c64f4e85..e33ce9d65efd 100644 --- a/cmd/githubgen/codeowners.go +++ b/cmd/githubgen/codeowners.go @@ -71,6 +71,7 @@ const distributionCodeownersHeader = ` ` type codeownersGenerator struct { + skipGithub bool } func (cg codeownersGenerator) generate(data *githubData) error { @@ -91,7 +92,7 @@ func (cg codeownersGenerator) generate(data *githubData) error { } var missingCodeowners []string var duplicateCodeowners []string - members, err := getGithubMembers() + members, err := cg.getGithubMembers() if err != nil { return err } @@ -109,7 +110,7 @@ func (cg codeownersGenerator) generate(data *githubData) error { duplicateCodeowners = append(duplicateCodeowners, codeowner) } } - if len(missingCodeowners) > 0 { + if len(missingCodeowners) > 0 && !cg.skipGithub { sort.Strings(missingCodeowners) return fmt.Errorf("codeowners are not members: %s", strings.Join(missingCodeowners, ", ")) } @@ -189,7 +190,11 @@ LOOP: return nil } -func getGithubMembers() (map[string]struct{}, error) { +func (cg codeownersGenerator) getGithubMembers() (map[string]struct{}, error) { + if cg.skipGithub { + // don't try to get organization members if no token is expected + return map[string]struct{}{}, nil + } githubToken := os.Getenv("GITHUB_TOKEN") if githubToken == "" { return nil, fmt.Errorf("Set the environment variable `GITHUB_TOKEN` to a PAT token to authenticate") diff --git a/cmd/githubgen/main.go b/cmd/githubgen/main.go index 09431fef0fc0..10e87c4ecfc3 100644 --- a/cmd/githubgen/main.go +++ b/cmd/githubgen/main.go @@ -32,6 +32,7 @@ type generator interface { func main() { folder := flag.String("folder", ".", "folder investigated for codeowners") allowlistFilePath := flag.String("allowlist", "cmd/githubgen/allowlist.txt", "path to a file containing an allowlist of members outside the OpenTelemetry organization") + skipGithubCheck := flag.Bool("skipgithub", false, "skip checking GitHub membership check for CODEOWNERS generator") flag.Parse() var generators []generator for _, arg := range flag.Args() { @@ -39,7 +40,7 @@ func main() { case "issue-templates": generators = append(generators, issueTemplatesGenerator{}) case "codeowners": - generators = append(generators, codeownersGenerator{}) + generators = append(generators, codeownersGenerator{skipGithub: *skipGithubCheck}) case "distributions": generators = append(generators, distributionsGenerator{}) default: @@ -47,7 +48,7 @@ func main() { } } if len(generators) == 0 { - generators = []generator{issueTemplatesGenerator{}, codeownersGenerator{}} + generators = []generator{issueTemplatesGenerator{}, codeownersGenerator{skipGithub: *skipGithubCheck}} } if err := run(*folder, *allowlistFilePath, generators); err != nil { log.Fatal(err) diff --git a/processor/spanprocessor/README.md b/processor/spanprocessor/README.md index 454b01fa0a07..10eae85904d3 100644 --- a/processor/spanprocessor/README.md +++ b/processor/spanprocessor/README.md @@ -81,6 +81,9 @@ span name that is the output after processing the previous rule. - `break_after_match` (default = false): specifies if processing of rules should stop after the first match. If it is false rule processing will continue to be performed over the modified span name. +- `keep_original_name` (default = false): specifies if the original span name should be kept after +processing the rules. If it is true, the original span name will be kept, +otherwise it will be replaced with the placeholders of the captured attributes. ```yaml span/to_attributes: @@ -92,7 +95,7 @@ span/to_attributes: - regexp-rule3 ... break_after_match: - + keep_original_name: ``` Example: @@ -106,6 +109,15 @@ span/to_attributes: to_attributes: rules: - ^\/api\/v1\/document\/(?P.*)\/update$ + +# This example will add the same new "documentId"="12345678" attribute, +# but now resulting in an unchanged span name (/api/v1/document/12345678/update). +span/to_attributes_keep_original_name: + name: + to_attributes: + keep_original_name: true + rules: + - ^\/api\/v1\/document\/(?P.*)\/update$ ``` ### Set status for span diff --git a/processor/spanprocessor/config.go b/processor/spanprocessor/config.go index 1f9c536a33de..b96d4dbbbc19 100644 --- a/processor/spanprocessor/config.go +++ b/processor/spanprocessor/config.go @@ -68,6 +68,11 @@ type ToAttributes struct { // match. If it is false rule processing will continue to be performed over the // modified span name. BreakAfterMatch bool `mapstructure:"break_after_match"` + + // KeepOriginalName specifies if the original span name should be kept after + // processing the rules. If it is true the original span name will be kept, + // otherwise it will be replaced with the placeholders of the captured attributes. + KeepOriginalName bool `mapstructure:"keep_original_name"` } type Status struct { diff --git a/processor/spanprocessor/config_test.go b/processor/spanprocessor/config_test.go index f0488fb1c0df..b4f3aa0e1d24 100644 --- a/processor/spanprocessor/config_test.go +++ b/processor/spanprocessor/config_test.go @@ -46,7 +46,19 @@ func TestLoadingConfig(t *testing.T) { expected: &Config{ Rename: Name{ ToAttributes: &ToAttributes{ - Rules: []string{`^\/api\/v1\/document\/(?P.*)\/update$`}, + Rules: []string{`^\/api\/v1\/document\/(?P.*)\/update$`}, + KeepOriginalName: false, + }, + }, + }, + }, + { + id: component.MustNewIDWithName("span", "to_attributes_keep_original_name"), + expected: &Config{ + Rename: Name{ + ToAttributes: &ToAttributes{ + Rules: []string{`^\/api\/v1\/document\/(?P.*)\/update$`}, + KeepOriginalName: true, }, }, }, diff --git a/processor/spanprocessor/span.go b/processor/spanprocessor/span.go index ec629879703d..0f2992dc4abe 100644 --- a/processor/spanprocessor/span.go +++ b/processor/spanprocessor/span.go @@ -213,7 +213,9 @@ func (sp *spanProcessor) processToAttributes(span ptrace.Span) { } // Set new span name. - span.SetName(sb.String()) + if !sp.config.Rename.ToAttributes.KeepOriginalName { + span.SetName(sb.String()) + } if sp.config.Rename.ToAttributes.BreakAfterMatch { // Stop processing, break after first match is requested. diff --git a/processor/spanprocessor/span_test.go b/processor/spanprocessor/span_test.go index c759feb344ad..c25a059d1f6d 100644 --- a/processor/spanprocessor/span_test.go +++ b/processor/spanprocessor/span_test.go @@ -414,8 +414,9 @@ func TestSpanProcessor_NilName(t *testing.T) { // TestSpanProcessor_ToAttributes func TestSpanProcessor_ToAttributes(t *testing.T) { testCases := []struct { - rules []string - breakAfterMatch bool + rules []string + breakAfterMatch bool + keepOriginalName bool testCase }{ { @@ -460,9 +461,24 @@ func TestSpanProcessor_ToAttributes(t *testing.T) { { rules: []string{ - `^\/api\/v1\/document\/(?P.*)\/update\/4$`, - `^\/api\/(?P.*)\/document\/(?P.*)\/update\/4$`, + `^\/api\/.*\/document\/(?P.*)\/update\/3$`, + `^\/api\/(?P.*)\/document\/.*\/update\/3$`}, + testCase: testCase{ + inputName: "/api/v1/document/321083210/update/3", + outputName: "/api/v1/document/321083210/update/3", + outputAttributes: map[string]any{ + "documentId": "321083210", + "version": "v1", + }, }, + breakAfterMatch: false, + keepOriginalName: true, + }, + + { + rules: []string{ + `^\/api\/v1\/document\/(?P.*)\/update\/4$`, + `^\/api\/(?P.*)\/document\/(?P.*)\/update\/4$`}, testCase: testCase{ inputName: "/api/v1/document/321083210/update/4", outputName: "/api/v1/document/{documentId}/update/4", @@ -491,6 +507,7 @@ func TestSpanProcessor_ToAttributes(t *testing.T) { for _, tc := range testCases { oCfg.Rename.ToAttributes.Rules = tc.rules oCfg.Rename.ToAttributes.BreakAfterMatch = tc.breakAfterMatch + oCfg.Rename.ToAttributes.KeepOriginalName = tc.keepOriginalName tp, err := factory.CreateTraces(context.Background(), processortest.NewNopSettings(), oCfg, consumertest.NewNop()) require.NoError(t, err) require.NotNil(t, tp) diff --git a/processor/spanprocessor/testdata/config.yaml b/processor/spanprocessor/testdata/config.yaml index 26c1b3fd2f68..c86e4c7b5d48 100644 --- a/processor/spanprocessor/testdata/config.yaml +++ b/processor/spanprocessor/testdata/config.yaml @@ -61,6 +61,15 @@ span/to_attributes: rules: - ^\/api\/v1\/document\/(?P.*)\/update$ +# This example will add the same new "documentId"="12345678" attribute, +# but now resulting in an unchanged span name (/api/v1/document/12345678/update). +span/to_attributes_keep_original_name: + name: + to_attributes: + keep_original_name: true + rules: + - ^\/api\/v1\/document\/(?P.*)\/update$ + # The following demonstrates renaming the span name to `{operation_website}` # and adding the attribute {Key: operation_website, Value: } # when the span has the following properties