Skip to content

Commit

Permalink
Added http ignore by method (#49)
Browse files Browse the repository at this point in the history
  • Loading branch information
tom-pytel authored Apr 21, 2021
1 parent 7a5c054 commit 4011a53
Show file tree
Hide file tree
Showing 13 changed files with 67 additions and 76 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ Environment Variable | Description | Default
| `SW_AGENT_DISABLE_PLUGINS` | Comma-delimited list of plugins to disable in the plugins directory (e.g. "mysql", "express"). | `` |
| `SW_IGNORE_SUFFIX` | The suffices of endpoints that will be ignored (not traced), comma separated | `.jpg,.jpeg,.js,.css,.png,.bmp,.gif,.ico,.mp3,.mp4,.html,.svg` |
| `SW_TRACE_IGNORE_PATH` | The paths of endpoints that will be ignored (not traced), comma separated | `` |
| `SW_HTTP_IGNORE_METHOD` | Comma-delimited list of http methods to ignore (GET, POST, HEAD, OPTIONS, etc...) | `` |
| `SW_SQL_TRACE_PARAMETERS` | If set to 'true' then SQL query parameters will be included | `false` |
| `SW_SQL_PARAMETERS_MAX_LENGTH` | The maximum string length of SQL parameters to log | `512` |
| `SW_MONGO_TRACE_PARAMETERS` | If set to 'true' then mongodb query parameters will be included | `false` |
Expand Down
13 changes: 12 additions & 1 deletion src/config/AgentConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,15 @@ export type AgentConfig = {
disablePlugins?: string;
ignoreSuffix?: string;
traceIgnorePath?: string;
httpIgnoreMethod?: string;
sqlTraceParameters?: boolean;
sqlParametersMaxLength?: number;
mongoTraceParameters?: boolean;
mongoParametersMaxLength?: number;
// the following is internal state computed from config values
reDisablePlugins?: RegExp;
reIgnoreOperation?: RegExp;
reHttpIgnoreMethod?: RegExp;
};

export function finalizeConfig(config: AgentConfig): void {
Expand All @@ -53,9 +55,10 @@ export function finalizeConfig(config: AgentConfig): void {
).join('|') + ')$'; // replaces ","

config.reIgnoreOperation = RegExp(`${ignoreSuffix}|${ignorePath}`);
config.reHttpIgnoreMethod = RegExp(`^(?:${config.httpIgnoreMethod!.split(',').map((s) => s.trim()).join('|')})$`, 'i');
}

export default {
const _config = {
serviceName: process.env.SW_AGENT_NAME || 'your-nodejs-service',
serviceInstance:
process.env.SW_AGENT_INSTANCE ||
Expand All @@ -70,10 +73,18 @@ export default {
disablePlugins: process.env.SW_AGENT_DISABLE_PLUGINS || '',
ignoreSuffix: process.env.SW_IGNORE_SUFFIX ?? '.jpg,.jpeg,.js,.css,.png,.bmp,.gif,.ico,.mp3,.mp4,.html,.svg',
traceIgnorePath: process.env.SW_TRACE_IGNORE_PATH || '',
httpIgnoreMethod: process.env.SW_HTTP_IGNORE_METHOD || '',
sqlTraceParameters: (process.env.SW_SQL_TRACE_PARAMETERS || '').toLowerCase() === 'true',
sqlParametersMaxLength: Math.trunc(Math.max(0, Number(process.env.SW_SQL_PARAMETERS_MAX_LENGTH))) || 512,
mongoTraceParameters: (process.env.SW_MONGO_TRACE_PARAMETERS || '').toLowerCase() === 'true',
mongoParametersMaxLength: Math.trunc(Math.max(0, Number(process.env.SW_MONGO_PARAMETERS_MAX_LENGTH))) || 512,
reDisablePlugins: RegExp(''), // temporary placeholder so Typescript doesn't throw a fit
reIgnoreOperation: RegExp(''),
reHttpIgnoreMethod: RegExp(''),
};

export default _config;

export function ignoreHttpMethodCheck(method: string): boolean {
return Boolean(method.match(_config.reHttpIgnoreMethod));
}
8 changes: 5 additions & 3 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,14 @@ class Agent {
return;
}

if (this.started) {
logger.warn('SkyWalking agent started more than once, subsequent options to start ignored.');
return;
}

Object.assign(config, options);
finalizeConfig(config);

if (this.started) {
throw new Error('SkyWalking agent is already started and can only be started once.');
}
logger.debug('Starting SkyWalking agent');

this.started = true;
Expand Down
11 changes: 8 additions & 3 deletions src/plugins/AxiosPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@
*
*/

import SwPlugin, {wrapPromise} from '../core/SwPlugin';
import SwPlugin from '../core/SwPlugin';
import { URL } from 'url';
import ContextManager from '../trace/context/ContextManager';
import { Component } from '../trace/Component';
import Tag from '../Tag';
import { SpanLayer } from '../proto/language-agent/Tracing_pb';
import DummySpan from '../trace/span/DummySpan';
import { ignoreHttpMethodCheck } from '../config/AgentConfig';
import PluginInstaller from '../core/PluginInstaller';

class AxiosPlugin implements SwPlugin {
Expand All @@ -44,7 +46,10 @@ class AxiosPlugin implements SwPlugin {
config = url ? {...url} : {};

const {origin, host, pathname: operation} = new URL(config.url); // TODO: this may throw invalid URL
const span = ContextManager.current.newExitSpan(operation, host, Component.AXIOS, Component.HTTP);
const method = (config.method || 'GET').toUpperCase();
const span = ignoreHttpMethodCheck(method)
? DummySpan.create()
: ContextManager.current.newExitSpan(operation, host, Component.AXIOS, Component.HTTP);

span.start();

Expand All @@ -56,7 +61,7 @@ class AxiosPlugin implements SwPlugin {
span.peer = host;

span.tag(Tag.httpURL(origin + operation));
span.tag(Tag.httpMethod((config.method || 'GET').toUpperCase()));
span.tag(Tag.httpMethod(method));

span.inject().items.forEach((item) => config.headers[item.key] = item.value);

Expand Down
7 changes: 5 additions & 2 deletions src/plugins/ExpressPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@ import { IncomingMessage, ServerResponse } from 'http';
import ContextManager from '../trace/context/ContextManager';
import { Component } from '../trace/Component';
import Tag from '../Tag';
import EntrySpan from '../trace/span/EntrySpan';
import { ContextCarrier } from '../trace/context/ContextCarrier';
import DummySpan from '../trace/span/DummySpan';
import { ignoreHttpMethodCheck } from '../config/AgentConfig';
import PluginInstaller from '../core/PluginInstaller';
import HttpPlugin from './HttpPlugin';

Expand All @@ -42,7 +43,9 @@ class ExpressPlugin implements SwPlugin {
router.handle = function(req: IncomingMessage, res: ServerResponse, next: any) {
const carrier = ContextCarrier.from((req as any).headers || {});
const operation = (req.url || '/').replace(/\?.*/g, '');
const span: EntrySpan = ContextManager.current.newEntrySpan(operation, carrier, Component.HTTP_SERVER) as EntrySpan;
const span = ignoreHttpMethodCheck(req.method ?? 'GET')
? DummySpan.create()
: ContextManager.current.newEntrySpan(operation, carrier, Component.HTTP_SERVER);

span.component = Component.EXPRESS;

Expand Down
16 changes: 11 additions & 5 deletions src/plugins/HttpPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,10 @@ import ContextManager from '../trace/context/ContextManager';
import { Component } from '../trace/Component';
import Tag from '../Tag';
import Span from '../trace/span/Span';
import ExitSpan from '../trace/span/ExitSpan';
import { SpanLayer } from '../proto/language-agent/Tracing_pb';
import { ContextCarrier } from '../trace/context/ContextCarrier';
import DummySpan from '../trace/span/DummySpan';
import { ignoreHttpMethodCheck } from '../config/AgentConfig';

class HttpPlugin implements SwPlugin {
readonly module = 'http';
Expand Down Expand Up @@ -59,7 +60,10 @@ class HttpPlugin implements SwPlugin {
};

const operation = pathname.replace(/\?.*$/g, '');
const span: ExitSpan = ContextManager.current.newExitSpan(operation, host, Component.HTTP) as ExitSpan;
const method = arguments[url instanceof URL || typeof url === 'string' ? 1 : 0]?.method || 'GET';
const span = ignoreHttpMethodCheck(method)
? DummySpan.create()
: ContextManager.current.newExitSpan(operation, host, Component.HTTP);

if (span.depth) // if we inherited from a higher level plugin then do nothing, higher level should do all the work and we don't duplicate here
return _request.apply(this, arguments);
Expand All @@ -72,7 +76,7 @@ class HttpPlugin implements SwPlugin {
span.peer = host;

span.tag(Tag.httpURL(protocol + '://' + host + pathname));
span.tag(Tag.httpMethod(arguments[url instanceof URL || typeof url === 'string' ? 1 : 0]?.method || 'GET'));
span.tag(Tag.httpMethod(method));

const copyStatusAndWrapEmit = (res: any) => {
span.tag(Tag.httpStatusCode(res.statusCode));
Expand Down Expand Up @@ -146,7 +150,9 @@ class HttpPlugin implements SwPlugin {
function _sw_request(this: any, req: IncomingMessage, res: ServerResponse, ...reqArgs: any[]) {
const carrier = ContextCarrier.from((req as any).headers || {});
const operation = (req.url || '/').replace(/\?.*/g, '');
const span = ContextManager.current.newEntrySpan(operation, carrier);
const span = ignoreHttpMethodCheck(req.method ?? 'GET')
? DummySpan.create()
: ContextManager.current.newEntrySpan(operation, carrier);

span.component = Component.HTTP_SERVER;

Expand All @@ -168,7 +174,7 @@ class HttpPlugin implements SwPlugin {
? `[${req.connection.remoteAddress}]:${req.connection.remotePort}`
: `${req.connection.remoteAddress}:${req.connection.remotePort}`);

span.tag(Tag.httpMethod(req.method));
span.tag(Tag.httpMethod(req.method ?? 'GET'));

const ret = handler();

Expand Down
7 changes: 1 addition & 6 deletions src/trace/context/DummyContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,10 @@ import Span from '../../trace/span/Span';
import DummySpan from '../../trace/span/DummySpan';
import Segment from '../../trace/context/Segment';
import { Component } from '../../trace/Component';
import { SpanType } from '../../proto/language-agent/Tracing_pb';
import { ContextCarrier } from './ContextCarrier';

export default class DummyContext implements Context {
span: Span = new DummySpan({
context: this,
operation: '',
type: SpanType.LOCAL,
});
span: Span = DummySpan.create(this);
segment: Segment = new Segment();
nSpans = 0;

Expand Down
10 changes: 2 additions & 8 deletions src/trace/context/SpanContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@

import config from '../../config/AgentConfig';
import Context from '../../trace/context/Context';
import DummyContext from '../../trace/context/DummyContext';
import Span from '../../trace/span/Span';
import DummySpan from '../../trace/span/DummySpan';
import Segment from '../../trace/context/Segment';
Expand Down Expand Up @@ -53,13 +52,8 @@ export default class SpanContext implements Context {
}

ignoreCheck(operation: string, type: SpanType): Span | undefined {
if (operation.match(config.reIgnoreOperation)) {
return new DummySpan({
context: new DummyContext(),
operation: '',
type,
});
}
if (operation.match(config.reIgnoreOperation))
return DummySpan.create();

return undefined;
}
Expand Down
11 changes: 11 additions & 0 deletions src/trace/span/DummySpan.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,19 @@

import Span from '../../trace/span/Span';
import { ContextCarrier } from '../context/ContextCarrier';
import Context from '../context/Context';
import { SpanType } from '../../proto/language-agent/Tracing_pb';
import DummyContext from '../context/DummyContext';

export default class DummySpan extends Span {
static create(context?: Context): DummySpan {
return new DummySpan({
context: context ?? new DummyContext(),
operation: '',
type: SpanType.LOCAL,
});
}

inject(): ContextCarrier {
return new ContextCarrier();
}
Expand Down
4 changes: 2 additions & 2 deletions src/trace/span/EntrySpan.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@
*
*/

import StackedSpan from '../../trace/span/StackedSpan';
import Span from '../../trace/span/Span';
import { SpanCtorOptions } from './Span';
import SegmentRef from '../../trace/context/SegmentRef';
import { SpanType } from '../../proto/language-agent/Tracing_pb';
import { ContextCarrier } from '../context/ContextCarrier';

export default class EntrySpan extends StackedSpan {
export default class EntrySpan extends Span {
constructor(options: SpanCtorOptions) {
super(
Object.assign(options, {
Expand Down
4 changes: 2 additions & 2 deletions src/trace/span/ExitSpan.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@
*
*/

import StackedSpan from '../../trace/span/StackedSpan';
import Span from '../../trace/span/Span';
import { SpanCtorOptions } from './Span';
import config from '../../config/AgentConfig';
import { SpanType } from '../../proto/language-agent/Tracing_pb';
import { ContextCarrier } from '../context/ContextCarrier';
import ContextManager from '../context/ContextManager';

export default class ExitSpan extends StackedSpan {
export default class ExitSpan extends Span {
constructor(options: SpanCtorOptions) {
super(
Object.assign(options, {
Expand Down
10 changes: 7 additions & 3 deletions src/trace/span/Span.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ export default abstract class Span {
operation: string;
layer = SpanLayer.UNKNOWN;
component = Component.UNKNOWN;
depth = 0;
inherit?: Component;

readonly tags: Tag[] = [];
Expand All @@ -74,12 +75,15 @@ export default abstract class Span {
}

start(): void {
this.startTime = new Date().getTime();
this.context.start(this);
if (++this.depth === 1) {
this.startTime = new Date().getTime();
this.context.start(this);
}
}

stop(): void {
this.context.stop(this);
if (--this.depth === 0)
this.context.stop(this);
}

async(): void {
Expand Down
41 changes: 0 additions & 41 deletions src/trace/span/StackedSpan.ts

This file was deleted.

0 comments on commit 4011a53

Please sign in to comment.