Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
37 changes: 1 addition & 36 deletions packages/browser/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@ import type { BrowserTransportOptions } from './transports/types';
*/
declare const __SENTRY_RELEASE__: string | undefined;

const DEFAULT_FLUSH_INTERVAL = 5000;

type BrowserSpecificOptions = BrowserClientReplayOptions &
BrowserClientProfilingOptions & {
/** If configured, this URL will be used as base URL for lazy loading integration. */
Expand Down Expand Up @@ -85,8 +83,6 @@ export type BrowserClientOptions = ClientOptions<BrowserTransportOptions> & Brow
* @see SentryClient for usage documentation.
*/
export class BrowserClient extends Client<BrowserClientOptions> {
private _logFlushIdleTimeout: ReturnType<typeof setTimeout> | undefined;
private _metricFlushIdleTimeout: ReturnType<typeof setTimeout> | undefined;
/**
* Creates a new Browser SDK instance.
*
Expand All @@ -110,6 +106,7 @@ export class BrowserClient extends Client<BrowserClientOptions> {

const { sendDefaultPii, sendClientReports, enableLogs, _experiments } = this._options;

// Flush logs and metrics when page becomes hidden (e.g., tab switch, navigation)
if (WINDOW.document && (sendClientReports || enableLogs || _experiments?.enableMetrics)) {
WINDOW.document.addEventListener('visibilitychange', () => {
if (WINDOW.document.visibilityState === 'hidden') {
Expand All @@ -126,38 +123,6 @@ export class BrowserClient extends Client<BrowserClientOptions> {
});
}

if (enableLogs) {
this.on('flush', () => {
_INTERNAL_flushLogsBuffer(this);
});

this.on('afterCaptureLog', () => {
if (this._logFlushIdleTimeout) {
clearTimeout(this._logFlushIdleTimeout);
}

this._logFlushIdleTimeout = setTimeout(() => {
_INTERNAL_flushLogsBuffer(this);
}, DEFAULT_FLUSH_INTERVAL);
});
}

if (_experiments?.enableMetrics) {
this.on('flush', () => {
_INTERNAL_flushMetricsBuffer(this);
});

this.on('afterCaptureMetric', () => {
if (this._metricFlushIdleTimeout) {
clearTimeout(this._metricFlushIdleTimeout);
}

this._metricFlushIdleTimeout = setTimeout(() => {
_INTERNAL_flushMetricsBuffer(this);
}, DEFAULT_FLUSH_INTERVAL);
});
}

if (sendDefaultPii) {
this.on('beforeSendSession', addAutoIpAddressToSession);
}
Expand Down
54 changes: 10 additions & 44 deletions packages/browser/test/client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ vi.mock('@sentry/core', async requireActual => {

describe('BrowserClient', () => {
let client: BrowserClient;
const DEFAULT_FLUSH_INTERVAL = 5000;

afterEach(() => {
vi.useRealTimers();
Expand Down Expand Up @@ -78,57 +77,24 @@ describe('BrowserClient', () => {
expect(sentryCore._INTERNAL_flushLogsBuffer).toHaveBeenCalledWith(client);
});

it('flushes logs on flush event', () => {
it('inherits log weight-based flushing from base Client', () => {
const scope = new Scope();
scope.setClient(client);

// Add some logs
sentryCore._INTERNAL_captureLog({ level: 'info', message: 'test log 1' }, scope);
sentryCore._INTERNAL_captureLog({ level: 'info', message: 'test log 2' }, scope);
// Spy on sendEnvelope to verify flushing happens
const sendEnvelopeSpy = vi.spyOn(client, 'sendEnvelope');

// Trigger flush event
client.emit('flush');

expect(sentryCore._INTERNAL_flushLogsBuffer).toHaveBeenCalledWith(client);
});

it('flushes logs after idle timeout', () => {
const scope = new Scope();
scope.setClient(client);

// Add a log which will trigger afterCaptureLog event
// Add a log and verify the base Client functionality works
sentryCore._INTERNAL_captureLog({ level: 'info', message: 'test log' }, scope);

// Fast forward the idle timeout
vi.advanceTimersByTime(DEFAULT_FLUSH_INTERVAL);

expect(sentryCore._INTERNAL_flushLogsBuffer).toHaveBeenCalledWith(client);
});

it('resets idle timeout when new logs are captured', () => {
const scope = new Scope();
scope.setClient(client);

// Add initial log
sentryCore._INTERNAL_captureLog({ level: 'info', message: 'test log 1' }, scope);

// Fast forward part of the idle timeout
vi.advanceTimersByTime(DEFAULT_FLUSH_INTERVAL / 2);
// Verify weight tracking is active
expect((client as any)._logWeight).toBeGreaterThan(0);

// Add another log which should reset the timeout
sentryCore._INTERNAL_captureLog({ level: 'info', message: 'test log 2' }, scope);

// Fast forward the remaining time
vi.advanceTimersByTime(DEFAULT_FLUSH_INTERVAL / 2);

// Should not have flushed yet since timeout was reset
expect(sentryCore._INTERNAL_flushLogsBuffer).not.toHaveBeenCalled();

// Fast forward the full timeout
vi.advanceTimersByTime(DEFAULT_FLUSH_INTERVAL);
// Trigger flush and verify it works
client.emit('flush');

// Now should have flushed both logs
expect(sentryCore._INTERNAL_flushLogsBuffer).toHaveBeenCalledWith(client);
expect(sendEnvelopeSpy).toHaveBeenCalledTimes(1);
expect((client as any)._logWeight).toBe(0);
});
});
});
Expand Down
Loading
Loading