88 lines
2.1 KiB
TypeScript
88 lines
2.1 KiB
TypeScript
import type { LightPlugin, LightClient, SentryEvent, LightConfig } from '../types';
|
|
import { isObject } from '../utils/helper';
|
|
|
|
interface SampleRateConfig {
|
|
error?: number;
|
|
performance?: number;
|
|
network?: number;
|
|
behavior?: number;
|
|
[key: string]: number | undefined;
|
|
}
|
|
|
|
interface SamplingPluginConfig {
|
|
rates?: SampleRateConfig;
|
|
}
|
|
|
|
class SamplingPlugin implements LightPlugin {
|
|
name = 'sampling';
|
|
version = '1.0.0';
|
|
|
|
private client!: LightClient;
|
|
private config: SamplingPluginConfig = {
|
|
rates: {
|
|
error: 1,
|
|
performance: 1,
|
|
network: 1,
|
|
behavior: 1,
|
|
},
|
|
};
|
|
|
|
setup(client: LightClient): void {
|
|
this.client = client;
|
|
this.loadConfig();
|
|
}
|
|
|
|
private loadConfig(): void {
|
|
const clientConfig = this.client.config as LightConfig;
|
|
if (clientConfig && isObject(clientConfig.sampling)) {
|
|
const samplingConfig = clientConfig.sampling as object;
|
|
if ('rates' in samplingConfig && isObject((samplingConfig as { rates?: object }).rates)) {
|
|
this.config.rates = { ...this.config.rates, ...((samplingConfig as { rates: object }).rates as object) } as SampleRateConfig;
|
|
}
|
|
}
|
|
}
|
|
|
|
private shouldSample(event: SentryEvent): boolean {
|
|
const globalRate = (this.client.config as LightConfig).sampleRate ?? 1;
|
|
if (globalRate <= 0) return false;
|
|
|
|
const typeRate = this.getTypeRate(event);
|
|
|
|
if (globalRate >= 1) {
|
|
return this.randomCheck(typeRate);
|
|
}
|
|
return this.randomCheck(globalRate * typeRate);
|
|
}
|
|
|
|
private getTypeRate(event: SentryEvent): number {
|
|
const rates = this.config.rates || {};
|
|
const type = event.type;
|
|
|
|
if (type === 'count') {
|
|
return 1;
|
|
}
|
|
|
|
const rate = rates[type];
|
|
return rate !== undefined ? rate : 1;
|
|
}
|
|
|
|
private randomCheck(rate: number): boolean {
|
|
if (rate >= 1) return true;
|
|
if (rate <= 0) return false;
|
|
return Math.random() < rate;
|
|
}
|
|
|
|
beforeReport(event: SentryEvent): SentryEvent | null {
|
|
if (!this.shouldSample(event)) {
|
|
return null;
|
|
}
|
|
return event;
|
|
}
|
|
|
|
destroy(): void {
|
|
// nothing to clean up
|
|
}
|
|
}
|
|
|
|
export default SamplingPlugin;
|