-
Notifications
You must be signed in to change notification settings - Fork 423
feat: Updated opentelemetry bridge to rely on configuration based transformation rules #3125
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
bizob2828
merged 14 commits into
newrelic:main
from
bizob2828:config-based-transformation-rules
Jun 2, 2025
Merged
Changes from 13 commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
e4372ff
chore: wrapped up config based transformation rules for servers
bizob2828 5f89253
chore: finished consumer rules
bizob2828 7c40eb3
chore: client db rule #1
bizob2828 e8ba33e
chore: built out db 1.24 rules need to do 1.17
bizob2828 c0bca69
chore: wrapped up db 1.17 rules, wrapped up http client rules, need t…
bizob2828 77af4f5
chore: wrapped up all the transformation rules, need to handle errors
bizob2828 a6afb88
refactor: cleaned up code, starting removing unused code
bizob2828 f375aac
chore: moved all bespoke logic to config
bizob2828 ae9ef17
chore: finished fixing tests
bizob2828 9953f94
docs: Added json schema for transformation rules
bizob2828 548ec81
chore: removed test file
bizob2828 69cab07
chore: abstracted some common util functions into `lib/otel/utils.js`
bizob2828 1f99da5
chore: removed commented out code
bizob2828 73f1463
chore: addressed PR feedback
bizob2828 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,158 @@ | ||
| { | ||
| "$schema": "http://json-schema.org/draft-07/schema#", | ||
| "title": "OpenTelemetry Transformation Rules", | ||
| "type": "array", | ||
| "items": { | ||
| "type": "object", | ||
| "required": ["name", "type", "matcher"], | ||
| "properties": { | ||
| "name": { "type": "string" }, | ||
| "type": { "type": "string" }, | ||
bizob2828 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| "matcher": { | ||
| "type": "object", | ||
| "required": ["required_span_kinds", "required_attribute_keys"], | ||
| "properties": { | ||
| "required_span_kinds": { | ||
| "type": "array", | ||
| "items": { "type": "string" } | ||
bizob2828 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| }, | ||
| "required_attribute_keys": { | ||
| "type": "array", | ||
| "items": { "type": "string" } | ||
| }, | ||
| "attribute_conditions": { | ||
| "type": "object", | ||
| "additionalProperties": { | ||
| "type": "array", | ||
| "items": { "type": "string" } | ||
| } | ||
| } | ||
| }, | ||
| "additionalProperties": false | ||
| }, | ||
| "attributes": { | ||
| "type": "array", | ||
| "items": { | ||
| "type": "object", | ||
| "properties": { | ||
| "key": { "type": "string" }, | ||
| "value": { "type": ["string", "number", "boolean"] }, | ||
| "template": { "type": "string" }, | ||
| "regex": { | ||
| "type": "object", | ||
| "required": ["statement"], | ||
| "properties": { | ||
| "statement": { "type": "string" }, | ||
| "flags": { "type": "string" }, | ||
| "groups": { | ||
| "type": "array", | ||
| "items": { | ||
| "type": "object", | ||
| "properties": { | ||
| "group": { "type": ["integer", "string"] }, | ||
| "key": { "type": "string" }, | ||
| "name": { "type": "string" }, | ||
| "regex": { | ||
| "type": "object", | ||
| "properties": { | ||
| "statement": { "type": "string" }, | ||
| "flags": { "type": "string" }, | ||
| "name": { "type": "integer" }, | ||
| "value": { "type": "integer" }, | ||
| "prefix": {"type": "string" } | ||
| } | ||
| }, | ||
| "value": { "type": ["integer", "string"] }, | ||
| "prefix": { "type": "string" } | ||
| }, | ||
| "additionalProperties": false | ||
| } | ||
| } | ||
| }, | ||
| "additionalProperties": false | ||
| }, | ||
| "target": { "type": "string" }, | ||
bizob2828 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| "name": { "type": "string" }, | ||
| "highSecurity": { "type": "boolean" }, | ||
| "mappings": { | ||
| "type": "array", | ||
| "items": { | ||
| "type": "object", | ||
| "properties": { | ||
| "key": { "type": "string" }, | ||
| "arguments": { "type": "string" }, | ||
| "body": { "type": "string" } | ||
| }, | ||
| "required": ["key", "arguments", "body"], | ||
| "additionalProperties": false | ||
| } | ||
| } | ||
| }, | ||
| "additionalProperties": false | ||
| } | ||
| }, | ||
| "transaction": { | ||
| "type": "object", | ||
| "properties": { | ||
| "type": { "type": "string" }, | ||
| "system": { "type": "string" }, | ||
| "name": { | ||
| "type": "object", | ||
| "properties": { | ||
| "verb": { "type": "string" }, | ||
| "path": { "type": "string" }, | ||
| "prefix": { "type": "string" }, | ||
| "templatePath": { "type": "string" }, | ||
| "templateValue": { "type": "string" }, | ||
| "value": { "type": "string" } | ||
| }, | ||
| "additionalProperties": false | ||
| }, | ||
| "url": { | ||
| "type": "object", | ||
| "properties": { | ||
| "template": { "type": "string" }, | ||
| "key": { "type": "string" }, | ||
| "mappings": { | ||
| "type": "array", | ||
| "items": { | ||
| "type": "object", | ||
| "properties": { | ||
| "key": { "type": "string" }, | ||
| "arguments": { "type": "string" }, | ||
| "body": { "type": "string" } | ||
| }, | ||
| "required": ["key", "arguments", "body"], | ||
| "additionalProperties": false | ||
| } | ||
| } | ||
| }, | ||
| "additionalProperties": false | ||
| } | ||
| }, | ||
| "additionalProperties": false | ||
| }, | ||
| "segment": { | ||
| "type": "object", | ||
| "properties": { | ||
| "name": { | ||
| "type": "object", | ||
| "properties": { | ||
| "template": { "type": "string" } | ||
| }, | ||
| "additionalProperties": false | ||
| }, | ||
| "host": { "type": ["string", "object"] }, | ||
| "system": { "type": "string" }, | ||
| "url": { "type": "string" }, | ||
| "operation": { "type": "string" }, | ||
| "type": { "type": "string" }, | ||
| "statement": { "type": "string" }, | ||
| "collection": { "type": "string" } | ||
| }, | ||
| "additionalProperties": false | ||
| } | ||
| }, | ||
| "additionalProperties": false | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,171 @@ | ||
| # OpenTelemetry Transformation Rules JSON Schema Documentation | ||
|
|
||
| This document describes the JSON schema for OpenTelemetry Transformation Rules, which define transaction events, trace segments, and time slice metrics are synthesized from span data. The intention is the attributes are processed when a span ends to ensure all the attributes are available for processing. The segment naming occurs when a span starts for all segments except for the transaction segment which is processed when the span ends. The schema is designed to be strict, ensuring that all rules conform to a defined structure and that no unknown properties are allowed. | ||
bizob2828 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| **Note**: This schema has only been tested with the Node.js agent, and while it is expected to work with other language agents, the implementation details may vary. | ||
|
|
||
| --- | ||
|
|
||
| ## Top-Level Structure | ||
|
|
||
| - **Type:** Array | ||
| The root of the document is an array of rule objects. | ||
|
|
||
| --- | ||
|
|
||
| ## Rule Object | ||
|
|
||
| Each item in the array is a rule object with the following properties: | ||
|
|
||
| ### Required Properties | ||
|
|
||
| - **name** (`string`): | ||
| The unique name of the transformation rule. | ||
|
|
||
| - **type** (`string`): | ||
| The type of the rule: `producer`, `consumer`, `external`, `server`, `db`, and `internal`. | ||
|
|
||
| - **matcher** (`object`): | ||
| Defines the criteria for matching spans to this rule. | ||
|
|
||
| --- | ||
|
|
||
| ### matcher | ||
|
|
||
| - **required_span_kinds** (`string[]`): | ||
| List of span kinds (e.g., `client`, `server`, `producer`) required for this rule to match. | ||
|
|
||
| - **required_attribute_keys** (`string[]`): | ||
| List of attribute keys that must be present on the span. | ||
|
|
||
| - **attribute_conditions** (`object`, optional): | ||
| An object where each key is an attribute name and the value is an array of allowed values for that attribute. | ||
|
|
||
| --- | ||
|
|
||
| ### attributes | ||
|
|
||
| - **attributes** (`array`, optional): | ||
| An array of attribute mapping objects, each describing how to extract or compute an attribute for the segment, transaction, or trace. | ||
|
|
||
| #### Attribute Mapping Object | ||
|
|
||
| - **key** (`string`, optional): | ||
| The key of the span attribute to extract. | ||
|
|
||
| - **value** (`string|number|boolean`, optional): | ||
| A literal value to use for the attribute. | ||
|
|
||
| - **template** (`string`, optional): | ||
| A template string for constructing the attribute value. | ||
|
|
||
| - **regex** (`object`, optional): | ||
| Describes how to extract values using regular expressions. | ||
| - **statement** (`string`, required): The regex pattern. | ||
| - **flags** (`string`, optional): Regex flags. | ||
| - **groups** (`array`, optional): Array of group extraction objects, each with: | ||
| - **group** (`integer|string`): The group index or name. | ||
| - **key** (`string`, optional): The span attribute key(used to remove from trace segment) | ||
| - **name** (`string`, optional): The attribute name for the extracted value. | ||
| - **regex** (`object`, optional): Nested regex extraction. | ||
| - **statement** (`string`, required): The regex pattern. | ||
| - **flags** (`string`, optional): Regex flags. | ||
| - **value** (`integer|string`, optional): Value to extract. | ||
| - **prefix** (`string`, optional): Prefix to add to the extracted value. | ||
|
|
||
| - **target** (`string`, optional): | ||
| Where to assign the attribute (`segment`, `transaction`, or `trace`). | ||
|
|
||
| - **name** (`string`, optional): | ||
| The name to use for the attribute in the target. | ||
|
|
||
| - **highSecurity** (`boolean`, optional): | ||
| If true, the attribute is omitted in high-security mode. | ||
|
|
||
| - **mappings** (`array`, optional): | ||
| Array of mapping objects for advanced transformations. Used to apply custom functions to the attribute value.(e.g. only include an attribute if it matches a certain condition) | ||
| - **key** (`string`): Mapping key. | ||
| - **arguments** (`string`): Mapping function arguments(comma delimited). | ||
| - **body** (`string`): Mapping function body. | ||
|
|
||
| --- | ||
|
|
||
| ### transaction | ||
|
|
||
| - **transaction** (`object`, optional): | ||
| Describes how to construct the transaction event. | ||
| - **type** (`string`, required): Transaction type. values: `web`, or `message` | ||
| - **system** (`string`, optional): messaging system span attribute.(consumer segments only) | ||
| - **name** (`object`, optional): Transaction naming details. | ||
| - **verb** (`string`, optional): span attribute to use as verb.(sever segments only) | ||
| - **path** (`string`, optional): span attribute to use as route(server segments only) | ||
| - **prefix** (`string`, optional): Prefix for the transaction name.(rpc server segments only) | ||
| - **templatePath** (`string`, optional): template for the partial transaction name. | ||
| - **templateValue** (`string`, optional): template for the transaction path. | ||
| - **value** (`string`, optional): Literal value for the transaction name. | ||
| - **url** (`object`, optional): URL construction details.(server segments only) | ||
| - **template** (`string`, optional): template to construct the URL. | ||
| - **key** (`string`, optional): span attriute to use as URL. | ||
| - **mappings** (`array`, optional): Array of mapping for advanced URL transformations. | ||
| - **key** (`string`): Mapping key. | ||
| - **arguments** (`string`): Mapping function arguments(comma delimited). | ||
| - **body** (`string`): Mapping function body. | ||
|
|
||
| --- | ||
|
|
||
| ### segment | ||
|
|
||
| - **segment** (`object`, optional): | ||
| Describes how to construct the trace segment. | ||
| - **name** (`object`, optional): Segment naming details. | ||
| - **template** (`string`, optional) | ||
| - **host** (`string|object`, optional): span attribute to use as host.(external segments only) | ||
| - **template** (`string`, optional): template for the host. | ||
| - **key** (`string`, optional): span attribute to use as host. | ||
| - **system** (`string`, optional): span attribute to use as system.(producer and rpc external segments only) | ||
| - **url** (`string`, optional): span attribute to use as URL(external segments only) | ||
| - **operation** (`string`, optional): span attribute to use as operation.(db segments only) | ||
| - **type** (`string`, optional): span attribute to use as type.(db segments only) | ||
| - **statement** (`string`, optional): span attribute to use as sql query(db segments only) | ||
| - **collection** (`string`, optional): span attribute to use as collection name(db segments only) | ||
|
|
||
| --- | ||
|
|
||
| ## Additional Notes | ||
|
|
||
| - **Strictness:** | ||
| The schema does not allow unknown properties at any level (`additionalProperties: false`). | ||
|
|
||
| - **Extensibility:** | ||
| If you add new fields or structures, update the schema accordingly. | ||
|
|
||
| - **Validation:** | ||
| Use this schema with a JSON Schema validator to ensure your transformation rules are well-formed and consistent. | ||
|
|
||
| --- | ||
|
|
||
| **Example Rule:** | ||
| ```json | ||
| { | ||
| "name": "Producer_1_30", | ||
| "type": "producer", | ||
| "matcher": { | ||
| "required_span_kinds": ["producer"], | ||
| "required_attribute_keys": ["messaging.system", "messaging.destination.name"] | ||
| }, | ||
| "attributes": [ | ||
| { | ||
| "key": "server.address", | ||
| "target": "segment", | ||
| "name": "host" | ||
| } | ||
| ], | ||
| "segment": { | ||
| "name": { | ||
| "template": "MessageBroker/${messaging.system}/${messaging.operation.name}/Produce/Named/${messaging.destination.name}" | ||
| } | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| --- | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.