Skip to content

Commit 4f1271e

Browse files
authored
Merge branch 'main' into fix-pg-instr
2 parents 054c21a + 4b9e3ad commit 4f1271e

File tree

25 files changed

+4402
-2098
lines changed

25 files changed

+4402
-2098
lines changed

.github/component_owners.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,10 @@ components:
7272
- blumamir
7373
packages/instrumentation-socket.io:
7474
- mottibec
75+
packages/instrumentation-sequelize:
76+
- seemk
77+
- t2t2
78+
- mhennoch
7579
packages/instrumentation-tedious: []
7680
# Unmaintained
7781
packages/instrumentation-typeorm:

.github/workflows/lint.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,14 @@ permissions:
1010
contents: read
1111

1212
jobs:
13-
build:
13+
lint:
1414
runs-on: ubuntu-latest
1515
steps:
1616
- uses: actions/checkout@v5
1717
- uses: actions/setup-node@v6
1818
with:
1919
node-version: 18
20-
cache: 'npm'
20+
cache: npm
2121
- run: npm ci --ignore-scripts
2222
- name: Lint
2323
run: |

.release-please-manifest.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
"packages/instrumentation-lru-memoizer": "0.52.0",
2828
"packages/instrumentation-mongoose": "0.54.0",
2929
"packages/instrumentation-runtime-node": "0.21.0",
30+
"packages/instrumentation-sequelize": "0.1.0",
3031
"packages/instrumentation-socket.io": "0.54.0",
3132
"packages/instrumentation-tedious": "0.26.0",
3233
"packages/instrumentation-typeorm": "0.8.0",

examples/web/docker/collector-config.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ receivers:
22
otlp:
33
protocols:
44
grpc:
5+
endpoint: 0.0.0.0:4317
56
http:
7+
endpoint: 0.0.0.0:4318
68
cors:
79
allowed_origins:
810
- http://*

package-lock.json

Lines changed: 2889 additions & 2043 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/instrumentation-aws-sdk/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ The instrumentations are collecting the following attributes:
6363
| Attribute Name | Type | Description | Example |
6464
| -------------- | ---- | ----------- | ------- |
6565
| `rpc.system` | string | Always equals "aws-api" | |
66-
| `rpc.method` | string | he name of the operation corresponding to the request, as returned by the AWS SDK. If the SDK does not provide a way to retrieve a name, the name of the command SHOULD be used, removing the suffix `Command` if present, resulting in a PascalCase name with no spaces. | `PutObject` |
66+
| `rpc.method` | string | The name of the operation corresponding to the request, as returned by the AWS SDK. If the SDK does not provide a way to retrieve a name, the name of the command SHOULD be used, removing the suffix `Command` if present, resulting in a PascalCase name with no spaces. | `PutObject` |
6767
| `rpc.service` | string | The name of the service to which a request is made, as returned by the AWS SDK. If the SDK does not provide a away to retrieve a name, the name of the SDK's client interface for a service SHOULD be used, removing the suffix `Client` if present, resulting in a PascalCase name with no spaces. | `S3`, `DynamoDB`, `Route53` |
6868
| `cloud.region` | string | Region name for the request | "eu-west-1" |
6969

packages/instrumentation-graphql/README.md

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -52,14 +52,15 @@ registerInstrumentations({
5252

5353
## Optional Parameters
5454

55-
| Param | type | Default Value | Description |
56-
|:-----------:|:-------:|:-------------:|:---------------------------------------------------------------------------------------------------------------------------------------------------------:|
57-
| mergeItems | boolean | false | Whether to merge list items into a single element. example: `users.*.name` instead of `users.0.name`, `users.1.name` |
58-
| depth | number | -1 | The maximum depth of fields/resolvers to instrument. When set to 0 it will not instrument fields and resolvers. When set to -1 it will instrument all fields and resolvers. |
59-
| allowValues | boolean | false | When set to true it will not remove attributes values from schema source. By default all values that can be sensitive are removed and replaced with "*" |
60-
| ignoreTrivialResolveSpans | boolean | false | Don't create spans for the execution of the default resolver on object properties. |
61-
| ignoreResolveSpans | boolean | false | Don't create spans for resolvers, regardless if they are trivial or not. |
62-
| responseHook | GraphQLInstrumentationExecutionResponseHook | undefined | Hook that allows adding custom span attributes based on the data returned from "execute" GraphQL action. |
55+
| Param | type | Default Value | Description |
56+
|:-------------------------:|:-------------------------------------------:|:-------------:|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------:|
57+
| mergeItems | boolean | false | Whether to merge list items into a single element. example: `users.*.name` instead of `users.0.name`, `users.1.name` |
58+
| depth | number | -1 | The maximum depth of fields/resolvers to instrument. When set to 0 it will not instrument fields and resolvers. When set to -1 it will instrument all fields and resolvers. |
59+
| allowValues | boolean | false | When set to true it will not remove attributes values from schema source. By default all values that can be sensitive are removed and replaced with "*" |
60+
| ignoreTrivialResolveSpans | boolean | false | Don't create spans for the execution of the default resolver on object properties. |
61+
| ignoreResolveSpans | boolean | false | Don't create spans for resolvers, regardless if they are trivial or not. |
62+
| flatResolveSpans | boolean | false | Place all resolve spans under the same parent instead of producing a nested tree structure. |
63+
| responseHook | GraphQLInstrumentationExecutionResponseHook | undefined | Hook that allows adding custom span attributes based on the data returned from "execute" GraphQL action. |
6364

6465
## Verbosity
6566

packages/instrumentation-graphql/src/internal-types.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,7 @@ export type validateType = (
8080
) => ReadonlyArray<graphqlTypes.GraphQLError>;
8181

8282
export interface GraphQLField {
83-
parent: api.Span;
8483
span: api.Span;
85-
error: Error | null;
8684
}
8785

8886
interface OtelGraphQLData {

packages/instrumentation-graphql/src/types.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,13 @@ export interface GraphQLInstrumentationConfig extends InstrumentationConfig {
5858
*/
5959
ignoreTrivialResolveSpans?: boolean;
6060

61+
/**
62+
* Place all resolve spans under the same parent instead of producing a nested tree structure.
63+
*
64+
* @default false
65+
*/
66+
flatResolveSpans?: boolean;
67+
6168
/**
6269
* Whether to merge list items into a single element.
6370
*

packages/instrumentation-graphql/src/utils.ts

Lines changed: 39 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -82,34 +82,33 @@ function createFieldIfNotExists(
8282
info: graphqlTypes.GraphQLResolveInfo,
8383
path: string[]
8484
): {
85-
field: any;
85+
field: GraphQLField;
8686
spanAdded: boolean;
8787
} {
8888
let field = getField(contextValue, path);
89+
if (field) {
90+
return { field, spanAdded: false };
91+
}
8992

90-
let spanAdded = false;
91-
92-
if (!field) {
93-
spanAdded = true;
94-
const parent = getParentField(contextValue, path);
95-
96-
field = {
97-
parent,
98-
span: createResolverSpan(
99-
tracer,
100-
getConfig,
101-
contextValue,
102-
info,
103-
path,
104-
parent.span
105-
),
106-
error: null,
107-
};
93+
const config = getConfig();
94+
const parentSpan = config.flatResolveSpans
95+
? getRootSpan(contextValue)
96+
: getParentFieldSpan(contextValue, path);
97+
98+
field = {
99+
span: createResolverSpan(
100+
tracer,
101+
getConfig,
102+
contextValue,
103+
info,
104+
path,
105+
parentSpan
106+
),
107+
};
108108

109-
addField(contextValue, path, field);
110-
}
109+
addField(contextValue, path, field);
111110

112-
return { spanAdded, field };
111+
return { field, spanAdded: true };
113112
}
114113

115114
function createResolverSpan(
@@ -187,22 +186,24 @@ function addField(contextValue: any, path: string[], field: GraphQLField) {
187186
field);
188187
}
189188

190-
function getField(contextValue: any, path: string[]) {
189+
function getField(contextValue: any, path: string[]): GraphQLField {
191190
return contextValue[OTEL_GRAPHQL_DATA_SYMBOL].fields[path.join('.')];
192191
}
193192

194-
function getParentField(contextValue: any, path: string[]) {
193+
function getParentFieldSpan(contextValue: any, path: string[]): api.Span {
195194
for (let i = path.length - 1; i > 0; i--) {
196195
const field = getField(contextValue, path.slice(0, i));
197196

198197
if (field) {
199-
return field;
198+
return field.span;
200199
}
201200
}
202201

203-
return {
204-
span: contextValue[OTEL_GRAPHQL_DATA_SYMBOL].span,
205-
};
202+
return getRootSpan(contextValue);
203+
}
204+
205+
function getRootSpan(contextValue: any): api.Span {
206+
return contextValue[OTEL_GRAPHQL_DATA_SYMBOL].span;
206207
}
207208

208209
function pathToArray(mergeItems: boolean, path: GraphQLPath): string[] {
@@ -443,24 +444,24 @@ export function wrapFieldResolver<TSource = any, TContext = any, TArgs = any>(
443444
const path = pathToArray(config.mergeItems, info && info.path);
444445
const depth = path.filter((item: any) => typeof item === 'string').length;
445446

446-
let field: any;
447+
let span: api.Span;
447448
let shouldEndSpan = false;
448449
if (config.depth >= 0 && config.depth < depth) {
449-
field = getParentField(contextValue, path);
450+
span = getParentFieldSpan(contextValue, path);
450451
} else {
451-
const newField = createFieldIfNotExists(
452+
const { field, spanAdded } = createFieldIfNotExists(
452453
tracer,
453454
getConfig,
454455
contextValue,
455456
info,
456457
path
457458
);
458-
field = newField.field;
459-
shouldEndSpan = newField.spanAdded;
459+
span = field.span;
460+
shouldEndSpan = spanAdded;
460461
}
461462

462463
return api.context.with(
463-
api.trace.setSpan(api.context.active(), field.span),
464+
api.trace.setSpan(api.context.active(), span),
464465
() => {
465466
try {
466467
const res = fieldResolver.call(
@@ -473,20 +474,20 @@ export function wrapFieldResolver<TSource = any, TContext = any, TArgs = any>(
473474
if (isPromise(res)) {
474475
return res.then(
475476
(r: any) => {
476-
handleResolveSpanSuccess(field.span, shouldEndSpan);
477+
handleResolveSpanSuccess(span, shouldEndSpan);
477478
return r;
478479
},
479480
(err: Error) => {
480-
handleResolveSpanError(field.span, err, shouldEndSpan);
481+
handleResolveSpanError(span, err, shouldEndSpan);
481482
throw err;
482483
}
483484
);
484485
} else {
485-
handleResolveSpanSuccess(field.span, shouldEndSpan);
486+
handleResolveSpanSuccess(span, shouldEndSpan);
486487
return res;
487488
}
488489
} catch (err: any) {
489-
handleResolveSpanError(field.span, err, shouldEndSpan);
490+
handleResolveSpanError(span, err, shouldEndSpan);
490491
throw err;
491492
}
492493
}

0 commit comments

Comments
 (0)