Skip to content

Commit

Permalink
feat: add _experimental_longtaskNoStartSession flag
Browse files Browse the repository at this point in the history
  • Loading branch information
Joozty committed Dec 4, 2024
1 parent 767d36e commit bba7b95
Show file tree
Hide file tree
Showing 17 changed files with 375 additions and 264 deletions.
8 changes: 1 addition & 7 deletions packages/web/src/SplunkContextManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,7 @@
import { Context, ContextManager, ROOT_CONTEXT } from '@opentelemetry/api'
import { unwrap } from 'shimmer'
import { getOriginalFunction, isFunction, wrapNatively } from './utils'

export interface ContextManagerConfig {
/** Enable async tracking of span parents */
async?: boolean
onBeforeContextEnd?: () => void
onBeforeContextStart?: () => void
}
import { ContextManagerConfig } from './types'

type EventListenerWithOrig = EventListener & { _orig?: EventListener }

Expand Down
13 changes: 12 additions & 1 deletion packages/web/src/SplunkLongTaskInstrumentation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,21 @@
import { InstrumentationBase, InstrumentationConfig } from '@opentelemetry/instrumentation'

import { VERSION } from './version'
import { getCurrentSessionState } from './session'
import { SplunkOtelWebConfig } from './types'

const LONGTASK_PERFORMANCE_TYPE = 'longtask'
const MODULE_NAME = 'splunk-longtask'

export class SplunkLongTaskInstrumentation extends InstrumentationBase {
private _longtaskObserver: PerformanceObserver | undefined

constructor(config: InstrumentationConfig = {}) {
private initOptions: SplunkOtelWebConfig

constructor(config: InstrumentationConfig = {}, initOptions: SplunkOtelWebConfig) {
super(MODULE_NAME, VERSION, Object.assign({}, config))

this.initOptions = initOptions
}

disable(): void {
Expand All @@ -52,6 +58,11 @@ export class SplunkLongTaskInstrumentation extends InstrumentationBase {
init(): void {}

private _createSpanFromEntry(entry: PerformanceEntry) {
if (!!this.initOptions._experimental_longtaskNoStartSession && !getCurrentSessionState()) {
// session expired, we do not want to spawn new session from long tasks
return
}

const span = this.tracer.startSpan(LONGTASK_PERFORMANCE_TYPE, {
startTime: entry.startTime,
})
Expand Down
153 changes: 13 additions & 140 deletions packages/web/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,27 +17,24 @@
*/

import './polyfill-safari10'
import { InstrumentationConfig, registerInstrumentations } from '@opentelemetry/instrumentation'
import { registerInstrumentations } from '@opentelemetry/instrumentation'
import {
ConsoleSpanExporter,
SimpleSpanProcessor,
BatchSpanProcessor,
ReadableSpan,
SpanExporter,
SpanProcessor,
BufferConfig,
AlwaysOffSampler,
AlwaysOnSampler,
ParentBasedSampler,
} from '@opentelemetry/sdk-trace-base'
import { WebTracerConfig } from '@opentelemetry/sdk-trace-web'
import { Attributes, diag, DiagConsoleLogger, DiagLogLevel } from '@opentelemetry/api'
import { SplunkDocumentLoadInstrumentation } from './SplunkDocumentLoadInstrumentation'
import { SplunkXhrPlugin } from './SplunkXhrPlugin'
import { SplunkFetchInstrumentation } from './SplunkFetchInstrumentation'
import {
SplunkUserInteractionInstrumentation,
SplunkUserInteractionInstrumentationConfig,
DEFAULT_AUTO_INSTRUMENTED_EVENTS,
DEFAULT_AUTO_INSTRUMENTED_EVENT_NAMES,
UserInteractionEventsConfig,
Expand All @@ -48,161 +45,33 @@ import { ERROR_INSTRUMENTATION_NAME, SplunkErrorInstrumentation } from './Splunk
import { generateId, getPluginConfig } from './utils'
import { getRumSessionId, initSessionTracking } from './session'
import { SplunkWebSocketInstrumentation } from './SplunkWebSocketInstrumentation'
import { WebVitalsInstrumentationConfig, initWebVitals } from './webvitals'
import { initWebVitals } from './webvitals'
import { SplunkLongTaskInstrumentation } from './SplunkLongTaskInstrumentation'
import { SplunkPageVisibilityInstrumentation } from './SplunkPageVisibilityInstrumentation'
import { SplunkConnectivityInstrumentation } from './SplunkConnectivityInstrumentation'
import {
SplunkPostDocLoadResourceInstrumentation,
SplunkPostDocLoadResourceInstrumentationConfig,
} from './SplunkPostDocLoadResourceInstrumentation'
import { SplunkPostDocLoadResourceInstrumentation } from './SplunkPostDocLoadResourceInstrumentation'
import { SplunkWebTracerProvider } from './SplunkWebTracerProvider'
import { FetchInstrumentationConfig } from '@opentelemetry/instrumentation-fetch'
import { XMLHttpRequestInstrumentationConfig } from '@opentelemetry/instrumentation-xml-http-request'
import { InternalEventTarget, SplunkOtelWebEventTarget } from './EventTarget'
import { ContextManagerConfig, SplunkContextManager } from './SplunkContextManager'
import { SplunkContextManager } from './SplunkContextManager'
import { Resource, ResourceAttributes } from '@opentelemetry/resources'
import { SemanticResourceAttributes } from '@opentelemetry/semantic-conventions'
import { SDK_INFO, _globalThis } from '@opentelemetry/core'
import { VERSION } from './version'
import { getSyntheticsRunId, SYNTHETICS_RUN_ID_ATTRIBUTE } from './synthetics'
import { SplunkSpanAttributesProcessor } from './SplunkSpanAttributesProcessor'
import { SessionBasedSampler } from './SessionBasedSampler'
import {
SocketIoClientInstrumentationConfig,
SplunkSocketIoClientInstrumentation,
} from './SplunkSocketIoClientInstrumentation'
import { SplunkSocketIoClientInstrumentation } from './SplunkSocketIoClientInstrumentation'
import { SplunkOTLPTraceExporter } from './exporters/otlp'
import { registerGlobal, unregisterGlobal } from './global-utils'
import { BrowserInstanceService } from './services/BrowserInstanceService'
import { SessionId } from './types'
import { SessionId } from './session'
import { SplunkOtelWebConfig, SplunkOtelWebExporterOptions, SplunkOtelWebOptionsInstrumentations } from './types'

export { SplunkExporterConfig } from './exporters/common'
export { SplunkZipkinExporter } from './exporters/zipkin'
export * from './SplunkWebTracerProvider'
export * from './SessionBasedSampler'

interface SplunkOtelWebOptionsInstrumentations {
connectivity?: boolean | InstrumentationConfig
document?: boolean | InstrumentationConfig
errors?: boolean
fetch?: boolean | FetchInstrumentationConfig
interactions?: boolean | SplunkUserInteractionInstrumentationConfig
longtask?: boolean | InstrumentationConfig
postload?: boolean | SplunkPostDocLoadResourceInstrumentationConfig
socketio?: boolean | SocketIoClientInstrumentationConfig
visibility?: boolean | InstrumentationConfig
websocket?: boolean | InstrumentationConfig
webvitals?: boolean | WebVitalsInstrumentationConfig
xhr?: boolean | XMLHttpRequestInstrumentationConfig
}

export interface SplunkOtelWebExporterOptions {
/**
* Allows remapping Span's attributes right before they're serialized.
* One potential use case of this method is to remove PII from the attributes.
*/
onAttributesSerializing?: (attributes: Attributes, span: ReadableSpan) => Attributes

/**
* Switch from zipkin to otlp for exporting
*/
otlp?: boolean
}

export interface SplunkOtelWebConfig {
/**
* If enabled, all spans are treated as activity and extend the duration of the session. Defaults to false.
*/
_experimental_allSpansExtendSession?: boolean

/** Allows http beacon urls */
allowInsecureBeacon?: boolean

/** Application name
* @deprecated Renamed to `applicationName`
*/
app?: string

/** Application name */
applicationName?: string

/** Destination for the captured data */
beaconEndpoint?: string

/**
* Destination for the captured data
* @deprecated Renamed to `beaconEndpoint`, or use realm
*/
beaconUrl?: string

/** Options for context manager */
context?: ContextManagerConfig

/** Sets session cookie to this domain */
cookieDomain?: string

/** Turns on/off internal debug logging */
debug?: boolean

/**
* Sets a value for the `environment` attribute (persists through calls to `setGlobalAttributes()`)
* */
deploymentEnvironment?: string

/**
* Sets a value for the `environment` attribute (persists through calls to `setGlobalAttributes()`)
* @deprecated Renamed to `deploymentEnvironment`
*/
environment?: string

/** Allows configuring how telemetry data is sent to the backend */
exporter?: SplunkOtelWebExporterOptions

/** Sets attributes added to every Span. */
globalAttributes?: Attributes

/**
* Applies for XHR, Fetch and Websocket URLs. URLs that partially match any regex in ignoreUrls will not be traced.
* In addition, URLs that are _exact matches_ of strings in ignoreUrls will also not be traced.
* */
ignoreUrls?: Array<string | RegExp>

/** Configuration for instrumentation modules. */
instrumentations?: SplunkOtelWebOptionsInstrumentations

/**
* The name of your organization’s realm. Automatically configures beaconUrl with correct URL
*/
realm?: string

/**
* Publicly-visible rum access token value. Please do not paste any other access token or auth value into here, as this
* will be visible to every user of your app
*/
rumAccessToken?: string

/**
* Publicly-visible `rumAuth` value. Please do not paste any other access token or auth value into here, as this
* will be visible to every user of your app
* @deprecated Renamed to rumAccessToken
*/
rumAuth?: string

/**
* Config options passed to web tracer
*/
tracer?: WebTracerConfig

/** Use local storage to save session ID instead of cookie */
useLocalStorage?: boolean

/**
* Sets a value for the 'app.version' attribute
*/
version?: string
}

interface SplunkOtelWebConfigInternal extends SplunkOtelWebConfig {
bufferSize?: number
bufferTimeout?: number
Expand Down Expand Up @@ -487,8 +356,12 @@ export const SplunkRum: SplunkOtelWebType = {
const instrumentations = INSTRUMENTATIONS.map(({ Instrument, confKey, disable }) => {
const pluginConf = getPluginConfig(processedOptions.instrumentations[confKey], pluginDefaults, disable)
if (pluginConf) {
// @ts-expect-error Can't mark in any way that processedOptions.instrumentations[confKey] is of specifc config type
const instrumentation = new Instrument(pluginConf)
const instrumentation =
Instrument === SplunkLongTaskInstrumentation
? new Instrument(pluginConf, options)
: // @ts-expect-error Can't mark in any way that processedOptions.instrumentations[confKey] is of specifc config type
new Instrument(pluginConf)

if (confKey === ERROR_INSTRUMENTATION_NAME && instrumentation instanceof SplunkErrorInstrumentation) {
_errorInstrumentation = instrumentation
}
Expand Down
62 changes: 0 additions & 62 deletions packages/web/src/local-storage-session.ts

This file was deleted.

22 changes: 22 additions & 0 deletions packages/web/src/session/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/**
*
* Copyright 2024 Splunk Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
export const SESSION_ID_LENGTH = 32
export const SESSION_DURATION_SECONDS = 4 * 60 * 60 // 4 hours
export const SESSION_DURATION_MS = SESSION_DURATION_SECONDS * 1000
export const SESSION_INACTIVITY_TIMEOUT_MS = 15 * 60 * 1000 // 15 minutes
export const SESSION_STORAGE_KEY = '_splunk_rum_sid'
Loading

0 comments on commit bba7b95

Please sign in to comment.