@sentry/core
Version:
Base implementation for all Sentry JavaScript SDKs
245 lines (210 loc) • 7.88 kB
JavaScript
Object.defineProperty(exports, '__esModule', { value: true });
const utils = require('@sentry/utils');
const baseclient = require('./baseclient.js');
const checkin = require('./checkin.js');
const hub = require('./hub.js');
const sessionflusher = require('./sessionflusher.js');
const hubextensions = require('./tracing/hubextensions.js');
const dynamicSamplingContext = require('./tracing/dynamicSamplingContext.js');
require('./tracing/spanstatus.js');
/**
* The Sentry Server Runtime Client SDK.
*/
class ServerRuntimeClient
extends baseclient.BaseClient {
/**
* Creates a new Edge SDK instance.
* @param options Configuration options for this SDK.
*/
constructor(options) {
// Server clients always support tracing
hubextensions.addTracingExtensions();
super(options);
}
/**
* @inheritDoc
*/
eventFromException(exception, hint) {
return utils.resolvedSyncPromise(utils.eventFromUnknownInput(hub.getCurrentHub, this._options.stackParser, exception, hint));
}
/**
* @inheritDoc
*/
eventFromMessage(
message,
// eslint-disable-next-line deprecation/deprecation
level = 'info',
hint,
) {
return utils.resolvedSyncPromise(
utils.eventFromMessage(this._options.stackParser, message, level, hint, this._options.attachStacktrace),
);
}
/**
* @inheritDoc
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
captureException(exception, hint, scope) {
// Check if the flag `autoSessionTracking` is enabled, and if `_sessionFlusher` exists because it is initialised only
// when the `requestHandler` middleware is used, and hence the expectation is to have SessionAggregates payload
// sent to the Server only when the `requestHandler` middleware is used
if (this._options.autoSessionTracking && this._sessionFlusher && scope) {
const requestSession = scope.getRequestSession();
// Necessary checks to ensure this is code block is executed only within a request
// Should override the status only if `requestSession.status` is `Ok`, which is its initial stage
if (requestSession && requestSession.status === 'ok') {
requestSession.status = 'errored';
}
}
return super.captureException(exception, hint, scope);
}
/**
* @inheritDoc
*/
captureEvent(event, hint, scope) {
// Check if the flag `autoSessionTracking` is enabled, and if `_sessionFlusher` exists because it is initialised only
// when the `requestHandler` middleware is used, and hence the expectation is to have SessionAggregates payload
// sent to the Server only when the `requestHandler` middleware is used
if (this._options.autoSessionTracking && this._sessionFlusher && scope) {
const eventType = event.type || 'exception';
const isException =
eventType === 'exception' && event.exception && event.exception.values && event.exception.values.length > 0;
// If the event is of type Exception, then a request session should be captured
if (isException) {
const requestSession = scope.getRequestSession();
// Ensure that this is happening within the bounds of a request, and make sure not to override
// Session Status if Errored / Crashed
if (requestSession && requestSession.status === 'ok') {
requestSession.status = 'errored';
}
}
}
return super.captureEvent(event, hint, scope);
}
/**
*
* @inheritdoc
*/
close(timeout) {
if (this._sessionFlusher) {
this._sessionFlusher.close();
}
return super.close(timeout);
}
/** Method that initialises an instance of SessionFlusher on Client */
initSessionFlusher() {
const { release, environment } = this._options;
if (!release) {
(typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && utils.logger.warn('Cannot initialise an instance of SessionFlusher if no release is provided!');
} else {
this._sessionFlusher = new sessionflusher.SessionFlusher(this, {
release,
environment,
});
}
}
/**
* Create a cron monitor check in and send it to Sentry.
*
* @param checkIn An object that describes a check in.
* @param upsertMonitorConfig An optional object that describes a monitor config. Use this if you want
* to create a monitor automatically when sending a check in.
*/
captureCheckIn(checkIn, monitorConfig, scope) {
const id = checkIn.status !== 'in_progress' && checkIn.checkInId ? checkIn.checkInId : utils.uuid4();
if (!this._isEnabled()) {
(typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && utils.logger.warn('SDK not enabled, will not capture checkin.');
return id;
}
const options = this.getOptions();
const { release, environment, tunnel } = options;
const serializedCheckIn = {
check_in_id: id,
monitor_slug: checkIn.monitorSlug,
status: checkIn.status,
release,
environment,
};
if (checkIn.status !== 'in_progress') {
serializedCheckIn.duration = checkIn.duration;
}
if (monitorConfig) {
serializedCheckIn.monitor_config = {
schedule: monitorConfig.schedule,
checkin_margin: monitorConfig.checkinMargin,
max_runtime: monitorConfig.maxRuntime,
timezone: monitorConfig.timezone,
};
}
const [dynamicSamplingContext, traceContext] = this._getTraceInfoFromScope(scope);
if (traceContext) {
serializedCheckIn.contexts = {
trace: traceContext,
};
}
const envelope = checkin.createCheckInEnvelope(
serializedCheckIn,
dynamicSamplingContext,
this.getSdkMetadata(),
tunnel,
this.getDsn(),
);
(typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && utils.logger.info('Sending checkin:', checkIn.monitorSlug, checkIn.status);
void this._sendEnvelope(envelope);
return id;
}
/**
* Method responsible for capturing/ending a request session by calling `incrementSessionStatusCount` to increment
* appropriate session aggregates bucket
*/
_captureRequestSession() {
if (!this._sessionFlusher) {
(typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && utils.logger.warn('Discarded request mode session because autoSessionTracking option was disabled');
} else {
this._sessionFlusher.incrementSessionStatusCount();
}
}
/**
* @inheritDoc
*/
_prepareEvent(event, hint, scope) {
if (this._options.platform) {
event.platform = event.platform || this._options.platform;
}
if (this._options.runtime) {
event.contexts = {
...event.contexts,
runtime: (event.contexts || {}).runtime || this._options.runtime,
};
}
if (this._options.serverName) {
event.server_name = event.server_name || this._options.serverName;
}
return super._prepareEvent(event, hint, scope);
}
/** Extract trace information from scope */
_getTraceInfoFromScope(
scope,
) {
if (!scope) {
return [undefined, undefined];
}
const span = scope.getSpan();
if (span) {
const samplingContext = span.transaction ? span.transaction.getDynamicSamplingContext() : undefined;
return [samplingContext, span.getTraceContext()];
}
const { traceId, spanId, parentSpanId, dsc } = scope.getPropagationContext();
const traceContext = {
trace_id: traceId,
span_id: spanId,
parent_span_id: parentSpanId,
};
if (dsc) {
return [dsc, traceContext];
}
return [dynamicSamplingContext.getDynamicSamplingContextFromClient(traceId, this, scope), traceContext];
}
}
exports.ServerRuntimeClient = ServerRuntimeClient;
//# sourceMappingURL=server-runtime-client.js.map