1+ import type { Client } from './client' ;
12import { getClient , getCurrentScope } from './currentScopes' ;
23import { DEBUG_BUILD } from './debug-build' ;
4+ import type { Scope } from './scope' ;
35import { getDynamicSamplingContextFromScope } from './tracing' ;
46import type { DynamicSamplingContext , LogEnvelope , LogItem } from './types-hoist/envelope' ;
57import type { Log , LogAttribute , LogSeverityLevel } from './types-hoist/log' ;
@@ -24,20 +26,7 @@ export function createLogEnvelopeItem(log: Log): LogItem {
2426 *
2527 * @params log - the log object which will be sent
2628 */
27- function addLog ( log : Log ) : void {
28- const client = getClient ( ) ;
29-
30- if ( ! client ) {
31- DEBUG_BUILD && logger . warn ( 'No client available, log will not be captured.' ) ;
32- return ;
33- }
34-
35- if ( ! client . getOptions ( ) . _experiments ?. enableLogs ) {
36- DEBUG_BUILD && logger . warn ( 'logging option not enabled, log will not be captured.' ) ;
37- return ;
38- }
39-
40- const scope = getCurrentScope ( ) ;
29+ function createLogEnvelope ( logs : Log [ ] , client : Client , scope : Scope ) : LogEnvelope {
4130 const dsc = getDynamicSamplingContextFromScope ( client , scope ) ;
4231
4332 const dsn = client . getDsn ( ) ;
@@ -46,17 +35,8 @@ function addLog(log: Log): void {
4635 trace : dropUndefinedKeys ( dsc ) as DynamicSamplingContext ,
4736 ...( dsn ? { dsn : dsnToString ( dsn ) } : { } ) ,
4837 } ;
49- if ( ! log . traceId ) {
50- log . traceId = dsc . trace_id ;
51- }
52- if ( ! log . timeUnixNano ) {
53- log . timeUnixNano = `${ new Date ( ) . getTime ( ) . toString ( ) } 000000` ;
54- }
55-
56- const envelope = createEnvelope < LogEnvelope > ( headers , [ createLogEnvelopeItem ( log ) ] ) ;
5738
58- // eslint-disable-next-line @typescript-eslint/no-floating-promises
59- void client . sendEnvelope ( envelope ) ;
39+ return createEnvelope < LogEnvelope > ( headers , logs . map ( createLogEnvelopeItem ) ) ;
6040}
6141
6242function valueToAttribute ( key : string , value : unknown ) : LogAttribute {
@@ -84,13 +64,56 @@ function valueToAttribute(key: string, value: unknown): LogAttribute {
8464 }
8565}
8666
67+ let GLOBAL_LOG_BUFFER : Log [ ] = [ ] ;
68+
69+ let isFlushingLogs = false ;
70+
71+ function addToLogBuffer ( client : Client , log : Log , scope : Scope ) : void {
72+ function sendLogs ( flushedLogs : Log [ ] ) : void {
73+ const envelope = createLogEnvelope ( flushedLogs , client , scope ) ;
74+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
75+ void client . sendEnvelope ( envelope ) ;
76+ }
77+
78+ if ( GLOBAL_LOG_BUFFER . length >= 100 ) {
79+ sendLogs ( GLOBAL_LOG_BUFFER ) ;
80+ GLOBAL_LOG_BUFFER = [ ] ;
81+ } else {
82+ GLOBAL_LOG_BUFFER . push ( log ) ;
83+ }
84+
85+ // this is the first time logs have been enabled, let's kick off an interval to flush them
86+ // we should only do this once.
87+ if ( ! isFlushingLogs ) {
88+ setInterval ( ( ) => {
89+ if ( GLOBAL_LOG_BUFFER . length > 0 ) {
90+ sendLogs ( GLOBAL_LOG_BUFFER ) ;
91+ GLOBAL_LOG_BUFFER = [ ] ;
92+ }
93+ } , 5000 ) ;
94+ }
95+ isFlushingLogs = true ;
96+ }
97+
8798/**
8899 * A utility function to be able to create methods like Sentry.info`...`
89100 *
90101 * The first parameter is bound with, e.g., const info = captureLog.bind(null, 'info')
91102 * The other parameters are in the format to be passed a tagged template, Sentry.info`hello ${world}`
92103 */
93104export function captureLog ( level : LogSeverityLevel , messages : string [ ] | string , ...values : unknown [ ] ) : void {
105+ const client = getClient ( ) ;
106+
107+ if ( ! client ) {
108+ DEBUG_BUILD && logger . warn ( 'No client available, log will not be captured.' ) ;
109+ return ;
110+ }
111+
112+ if ( ! client . getOptions ( ) . _experiments ?. enableLogs ) {
113+ DEBUG_BUILD && logger . warn ( 'logging option not enabled, log will not be captured.' ) ;
114+ return ;
115+ }
116+
94117 const message = Array . isArray ( messages )
95118 ? messages . reduce ( ( acc , str , i ) => acc + str + ( values [ i ] ?? '' ) , '' )
96119 : messages ;
@@ -103,11 +126,18 @@ export function captureLog(level: LogSeverityLevel, messages: string[] | string,
103126 } ,
104127 } ) ;
105128 }
106- addLog ( {
129+
130+ const scope = getCurrentScope ( ) ;
131+
132+ const log : Log = {
107133 severityText : level ,
108134 body : {
109135 stringValue : message ,
110136 } ,
111137 attributes : attributes ,
112- } ) ;
138+ timeUnixNano : `${ new Date ( ) . getTime ( ) . toString ( ) } 000000` ,
139+ traceId : scope . getPropagationContext ( ) . traceId ,
140+ } ;
141+
142+ addToLogBuffer ( client , log , scope ) ;
113143}
0 commit comments