Skip to content

chore(maintenance): migrate tracer utility to biome #2809

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
merged 4 commits into from
Jul 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 4 additions & 9 deletions packages/tracer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@
"build:cjs": "tsc --build tsconfig.json && echo '{ \"type\": \"commonjs\" }' > lib/cjs/package.json",
"build:esm": "tsc --build tsconfig.esm.json && echo '{ \"type\": \"module\" }' > lib/esm/package.json",
"build": "npm run build:esm & npm run build:cjs",
"lint": "eslint --ext .ts,.js --no-error-on-unmatched-pattern .",
"lint-fix": "eslint --fix --ext .ts,.js --no-error-on-unmatched-pattern .",
"lint": "biome lint .",
"lint:fix": "biome check --write .",
"prepack": "node ../../.github/scripts/release_patch_package_json.js ."
},
"homepage": "https://github.com/aws-powertools/powertools-lambda-typescript/tree/main/packages/tracer#readme",
Expand Down Expand Up @@ -69,17 +69,12 @@
"lib/cjs/middleware/middy.d.ts",
"lib/esm/middleware/middy.d.ts"
],
"types": [
"lib/cjs/types/index.d.ts",
"lib/esm/types/index.d.ts"
]
"types": ["lib/cjs/types/index.d.ts", "lib/esm/types/index.d.ts"]
}
},
"types": "./lib/cjs/index.d.ts",
"main": "./lib/cjs/index.js",
"files": [
"lib"
],
"files": ["lib"],
"repository": {
"type": "git",
"url": "git+https://github.com/aws-powertools/powertools-lambda-typescript.git"
Expand Down
42 changes: 18 additions & 24 deletions packages/tracer/src/Tracer.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
import type { Handler } from 'aws-lambda';
import { Utility } from '@aws-lambda-powertools/commons';
import type {
AsyncHandler,
SyncHandler,
HandlerMethodDecorator,
SyncHandler,
} from '@aws-lambda-powertools/commons/types';
import type { Handler } from 'aws-lambda';
import type { Segment, Subsegment } from 'aws-xray-sdk-core';
import xraySdk from 'aws-xray-sdk-core';
import { EnvironmentVariablesService } from './config/EnvironmentVariablesService.js';
import { ProviderService } from './provider/ProviderService.js';
import type { ConfigServiceInterface } from './types/ConfigServiceInterface.js';
import type { ProviderServiceInterface } from './types/ProviderService.js';
import type {
TracerInterface,
TracerOptions,
AnyClass,
MethodDecorator,
CaptureLambdaHandlerOptions,
CaptureMethodOptions,
MethodDecorator,
TracerInterface,
TracerOptions,
} from './types/Tracer.js';
import { ProviderService } from './provider/ProviderService.js';
import type { ProviderServiceInterface } from './types/ProviderService.js';
import type { Segment, Subsegment } from 'aws-xray-sdk-core';
import xraySdk from 'aws-xray-sdk-core';
const { Subsegment: XraySubsegment } = xraySdk;

/**
Expand Down Expand Up @@ -372,22 +372,16 @@ class Tracer extends Utility implements TracerInterface {
options?: CaptureLambdaHandlerOptions
): HandlerMethodDecorator {
return (_target, _propertyKey, descriptor) => {
/**
* The descriptor.value is the method this decorator decorates, it cannot be undefined.
*/
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
// biome-ignore lint/style/noNonNullAssertion: The descriptor.value is the method this decorator decorates, it cannot be undefined.
const originalMethod = descriptor.value!;

// eslint-disable-next-line @typescript-eslint/no-this-alias
const tracerRef = this;
// Use a function() {} instead of an () => {} arrow function so that we can
// access `myClass` as `this` in a decorated `myClass.myMethod()`.
descriptor.value = function (this: Handler, event, context, callback) {
// eslint-disable-next-line @typescript-eslint/no-this-alias
const handlerRef: Handler = this;

if (!tracerRef.isTracingEnabled()) {
return originalMethod.apply(handlerRef, [event, context, callback]);
return originalMethod.apply(this, [event, context, callback]);
}

return tracerRef.provider.captureAsyncFunc(
Expand All @@ -397,7 +391,7 @@ class Tracer extends Utility implements TracerInterface {
tracerRef.addServiceNameAnnotation();
let result: unknown;
try {
result = await originalMethod.apply(handlerRef, [
result = await originalMethod.apply(this, [
event,
context,
callback,
Expand All @@ -413,7 +407,7 @@ class Tracer extends Utility implements TracerInterface {
subsegment?.close();
} catch (error) {
console.warn(
`Failed to close or serialize segment %s. We are catching the error but data might be lost.`,
'Failed to close or serialize segment %s. We are catching the error but data might be lost.',
subsegment?.name,
error
);
Expand Down Expand Up @@ -469,8 +463,7 @@ class Tracer extends Utility implements TracerInterface {
options?: CaptureMethodOptions
): MethodDecorator<T> {
return (_target, propertyKey, descriptor) => {
// The descriptor.value is the method this decorator decorates, it cannot be undefined.
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
// biome-ignore lint/style/noNonNullAssertion: The descriptor.value is the method this decorator decorates, it cannot be undefined.
const originalMethod = descriptor.value!;

// eslint-disable-next-line @typescript-eslint/no-this-alias
Expand All @@ -490,7 +483,8 @@ class Tracer extends Utility implements TracerInterface {
return tracerRef.provider.captureAsyncFunc(
subsegmentName,
async (subsegment) => {
let result;
// biome-ignore lint/suspicious/noExplicitAny: we don't know the type of the result because we're decorating arbitrary functions
let result: any;
try {
result = await originalMethod.apply(this, [...args]);
if (options?.captureResponse ?? true) {
Expand All @@ -505,7 +499,7 @@ class Tracer extends Utility implements TracerInterface {
subsegment?.close();
} catch (error) {
console.warn(
`Failed to close or serialize segment %s. We are catching the error but data might be lost.`,
'Failed to close or serialize segment %s. We are catching the error but data might be lost.',
subsegment?.name,
error
);
Expand Down Expand Up @@ -702,7 +696,7 @@ class Tracer extends Utility implements TracerInterface {
public setSegment(segment: Segment | Subsegment): void {
if (!this.isTracingEnabled()) return;

return this.provider.setSegment(segment);
this.provider.setSegment(segment);
}

/**
Expand Down
2 changes: 1 addition & 1 deletion packages/tracer/src/config/EnvironmentVariablesService.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ConfigServiceInterface } from '../types/ConfigServiceInterface.js';
import { EnvironmentVariablesService as CommonEnvironmentVariablesService } from '@aws-lambda-powertools/commons';
import type { ConfigServiceInterface } from '../types/ConfigServiceInterface.js';

class EnvironmentVariablesService
extends CommonEnvironmentVariablesService
Expand Down
8 changes: 4 additions & 4 deletions packages/tracer/src/middleware/middy.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { TRACER_KEY } from '@aws-lambda-powertools/commons';
import type { Tracer } from '../Tracer.js';
import type { Segment, Subsegment } from 'aws-xray-sdk-core';
import type { CaptureLambdaHandlerOptions } from '../types/Tracer.js';
import type {
MiddlewareLikeObj,
MiddyLikeRequest,
} from '@aws-lambda-powertools/commons/types';
import type { Segment, Subsegment } from 'aws-xray-sdk-core';
import type { Tracer } from '../Tracer.js';
import type { CaptureLambdaHandlerOptions } from '../types/Tracer.js';

/**
* A middy middleware automating capture of metadata and annotations on segments or subsegments for a Lambda Handler.
Expand Down Expand Up @@ -75,7 +75,7 @@ const captureLambdaHandler = (
handlerSegment.close();
} catch (error) {
console.warn(
`Failed to close or serialize segment %s. We are catching the error but data might be lost.`,
'Failed to close or serialize segment %s. We are catching the error but data might be lost.',
handlerSegment.name,
error
);
Expand Down
19 changes: 9 additions & 10 deletions packages/tracer/src/provider/ProviderService.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import type { Logger, Segment, Subsegment } from 'aws-xray-sdk-core';
import xraySdk from 'aws-xray-sdk-core';
import type { Namespace } from 'cls-hooked';
import type {
ProviderServiceInterface,
ContextMissingStrategy,
HttpSubsegment,
ProviderServiceInterface,
} from '../types/ProviderService.js';
import type { Segment, Subsegment, Logger } from 'aws-xray-sdk-core';
import xraySdk from 'aws-xray-sdk-core';
const {
captureAWS,
captureAWSClient,
Expand All @@ -21,16 +21,16 @@ const {
setDaemonAddress,
setLogger,
} = xraySdk;
import { addUserAgentMiddleware } from '@aws-lambda-powertools/commons';
import { subscribe } from 'node:diagnostics_channel';
import http from 'node:http';
import https from 'node:https';
import { addUserAgentMiddleware } from '@aws-lambda-powertools/commons';
import type { DiagnosticsChannel } from 'undici-types';
import {
findHeaderAndDecode,
getOriginURL,
isHttpSubsegment,
} from './utilities.js';
import type { DiagnosticsChannel } from 'undici-types';
import http from 'node:http';
import https from 'node:https';

class ProviderService implements ProviderServiceInterface {
/**
Expand All @@ -50,8 +50,7 @@ class ProviderService implements ProviderServiceInterface {
public captureAWSv3Client<T>(service: T): T {
addUserAgentMiddleware(service, 'tracer');

// Type must be aliased as any because of this https://github.com/aws/aws-xray-sdk-node/issues/439#issuecomment-859715660
// eslint-disable-next-line @typescript-eslint/no-explicit-any
// biome-ignore lint/suspicious/noExplicitAny: Type must be aliased as any because of this https://github.com/aws/aws-xray-sdk-node/issues/439#issuecomment-859715660
return captureAWSv3Client(service as any);
}

Expand Down Expand Up @@ -150,7 +149,7 @@ class ProviderService implements ProviderServiceInterface {
response: {
status,
...(contentLenght && {
content_length: parseInt(contentLenght),
content_length: Number.parseInt(contentLenght),
}),
},
};
Expand Down
4 changes: 2 additions & 2 deletions packages/tracer/src/provider/utilities.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { HttpSubsegment } from '../types/ProviderService.js';
import type { Segment, Subsegment } from 'aws-xray-sdk-core';
import { URL } from 'node:url';
import type { Segment, Subsegment } from 'aws-xray-sdk-core';
import type { HttpSubsegment } from '../types/ProviderService.js';

const decoder = new TextDecoder();

Expand Down
2 changes: 1 addition & 1 deletion packages/tracer/src/types/ProviderService.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { Namespace } from 'cls-hooked';
import type { Segment, Subsegment } from 'aws-xray-sdk-core';
import type { Namespace } from 'cls-hooked';

type ContextMissingStrategy =
| 'LOG_ERROR'
Expand Down
12 changes: 6 additions & 6 deletions packages/tracer/src/types/Tracer.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { ConfigServiceInterface } from './ConfigServiceInterface.js';
import type { HandlerMethodDecorator } from '@aws-lambda-powertools/commons/types';
import type { Segment, Subsegment } from 'aws-xray-sdk-core';
import type { ConfigServiceInterface } from './ConfigServiceInterface.js';

/**
* Options for the tracer class to be used during initialization.
Expand Down Expand Up @@ -99,9 +99,9 @@ type CaptureMethodOptions = {
captureResponse?: boolean;
};

// eslint-disable-next-line @typescript-eslint/no-explicit-any
// biome-ignore lint/suspicious/noExplicitAny: this is a generic type that is intentionally open
type AnyClassMethod = (...args: any[]) => any;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
// biome-ignore lint/suspicious/noExplicitAny: this is a generic type that is intentionally open
type AnyClass = new (...args: any[]) => any;

type MethodDecorator<T extends AnyClass> = (
Expand All @@ -115,9 +115,9 @@ interface TracerInterface {
addResponseAsMetadata(data?: unknown, methodName?: string): void;
addServiceNameAnnotation(): void;
annotateColdStart(): void;
captureAWS<T>(aws: T): void | T;
captureAWSv3Client<T>(service: T): void | T;
captureAWSClient<T>(service: T): void | T;
captureAWS<T>(aws: T): undefined | T;
captureAWSv3Client<T>(service: T): undefined | T;
captureAWSClient<T>(service: T): undefined | T;
captureLambdaHandler(
options?: CaptureLambdaHandlerOptions
): HandlerMethodDecorator;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Tracer } from '../../src/Tracer.js';
import type { Callback, Context } from 'aws-lambda';
import AWS from 'aws-sdk';
import { Tracer } from '../../src/Tracer.js';
import { httpRequest } from '../helpers/httpRequest.js';

const serviceName =
Expand Down Expand Up @@ -41,7 +41,7 @@ export class MyFunctionBase {
event: CustomEvent,
_context: Context,
_callback: Callback<unknown>
): void | Promise<unknown> {
): unknown {
tracer.putAnnotation(customAnnotationKey, customAnnotationValue);
tracer.putMetadata(customMetadataKey, customMetadataValue);

Expand Down Expand Up @@ -84,7 +84,7 @@ class MyFunctionWithDecorator extends MyFunctionBase {
event: CustomEvent,
_context: Context,
_callback: Callback<unknown>
): void | Promise<unknown> {
): unknown {
return super.handler(event, _context, _callback);
}

Expand All @@ -103,7 +103,7 @@ class MyFunctionWithDecoratorCaptureResponseFalse extends MyFunctionBase {
event: CustomEvent,
_context: Context,
_callback: Callback<unknown>
): void | Promise<unknown> {
): unknown {
return super.handler(event, _context, _callback);
}

Expand Down
10 changes: 5 additions & 5 deletions packages/tracer/tests/e2e/allFeatures.decorator.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
*
* @group e2e/tracer/decorator
*/
import { join } from 'node:path';
import { TestStack } from '@aws-lambda-powertools/testing-utils';
import { TestDynamodbTable } from '@aws-lambda-powertools/testing-utils/resources/dynamodb';
import { join } from 'node:path';
import { TracerTestNodejsFunction } from '../helpers/resources.js';
import {
assertAnnotation,
Expand All @@ -19,11 +19,11 @@ import {
splitSegmentsByName,
} from '../helpers/tracesUtils.js';
import {
commonEnvironmentVars,
RESOURCE_NAME_PREFIX,
SETUP_TIMEOUT,
TEARDOWN_TIMEOUT,
TEST_CASE_TIMEOUT,
commonEnvironmentVars,
} from './constants.js';

/**
Expand All @@ -35,7 +35,7 @@ import {
* Each stack must use a unique `serviceName` as it's used to for retrieving the trace.
* Using the same one will result in traces from different test cases mixing up.
*/
describe(`Tracer E2E tests, all features with decorator instantiation`, () => {
describe('Tracer E2E tests, all features with decorator instantiation', () => {
const testStack = new TestStack({
stackNameProps: {
stackNamePrefix: RESOURCE_NAME_PREFIX,
Expand Down Expand Up @@ -265,14 +265,14 @@ describe(`Tracer E2E tests, all features with decorator instantiation`, () => {
if (!metadata) {
fail('metadata is missing');
}
expect(metadata['AllFlagsOn'][expectedCustomMetadataKey]).toEqual(
expect(metadata.AllFlagsOn[expectedCustomMetadataKey]).toEqual(
expectedCustomMetadataValue
);

const shouldThrowAnError = i === invocationCount - 1;
if (!shouldThrowAnError) {
// Assert that the metadata object contains the response
expect(metadata['AllFlagsOn']['index.handler response']).toEqual(
expect(metadata.AllFlagsOn['index.handler response']).toEqual(
expectedCustomResponseValue
);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Tracer } from '../../src/index.js';
import type { Context } from 'aws-lambda';
import AWS from 'aws-sdk';
import type { Subsegment } from 'aws-xray-sdk-core';
import { Tracer } from '../../src/index.js';
import { httpRequest } from '../helpers/httpRequest.js';

const serviceName =
Expand Down
Loading