@@ -222,9 +222,8 @@ func TestLoggerBackend_StackTrace(t *testing.T) {
222222}
223223
224224func TestLoggerBackend_Tags (t * testing.T ) {
225- backend := newLoggerBackend (10 )
226-
227225 t .Run ("includes tags in log entry" , func (t * testing.T ) {
226+ backend := newLoggerBackend (10 )
228227 record := NewRecord (LogDebug , "tagged message" )
229228 backend .Add (record , WithTags ([]string {"service:api" , "version:1.2.3" }))
230229
@@ -236,4 +235,144 @@ func TestLoggerBackend_Tags(t *testing.T) {
236235
237236 assert .Equal (t , "service:api,version:1.2.3" , logs .Logs [0 ].Tags )
238237 })
238+
239+ t .Run ("same message with different tags are separate entries" , func (t * testing.T ) {
240+ backend := newLoggerBackend (10 )
241+ record1 := NewRecord (LogDebug , "shared message" )
242+ record2 := NewRecord (LogDebug , "shared message" )
243+
244+ backend .Add (record1 , WithTags ([]string {"env:prod" }))
245+ backend .Add (record2 , WithTags ([]string {"env:staging" }))
246+
247+ payload := backend .Payload ()
248+ require .NotNil (t , payload )
249+
250+ logs := payload .(transport.Logs )
251+ require .Len (t , logs .Logs , 2 , "Should have two separate log entries for different tags" )
252+
253+ // Extract tags for comparison
254+ tagSet := make (map [string ]bool )
255+ for _ , log := range logs .Logs {
256+ tagSet [log .Tags ] = true
257+ assert .Equal (t , "shared message" , log .Message )
258+ assert .Equal (t , uint32 (1 ), log .Count )
259+ }
260+ assert .True (t , tagSet ["env:prod" ], "Should contain env:prod tag" )
261+ assert .True (t , tagSet ["env:staging" ], "Should contain env:staging tag" )
262+ })
263+
264+ t .Run ("same message and tags increments count" , func (t * testing.T ) {
265+ backend := newLoggerBackend (10 )
266+ tags := []string {"service:api" , "version:1.0" }
267+
268+ backend .Add (NewRecord (LogWarn , "repeated message" ), WithTags (tags ))
269+ backend .Add (NewRecord (LogWarn , "repeated message" ), WithTags (tags ))
270+ backend .Add (NewRecord (LogWarn , "repeated message" ), WithTags (tags ))
271+
272+ payload := backend .Payload ()
273+ require .NotNil (t , payload )
274+
275+ logs := payload .(transport.Logs )
276+ require .Len (t , logs .Logs , 1 , "Should deduplicate logs with same message and tags" )
277+
278+ assert .Equal (t , "repeated message" , logs .Logs [0 ].Message )
279+ assert .Equal (t , "service:api,version:1.0" , logs .Logs [0 ].Tags )
280+ assert .Equal (t , uint32 (3 ), logs .Logs [0 ].Count )
281+ })
282+
283+ t .Run ("empty tags slice results in empty tags string" , func (t * testing.T ) {
284+ backend := newLoggerBackend (10 )
285+ record := NewRecord (LogDebug , "no tags message" )
286+ backend .Add (record , WithTags ([]string {}))
287+
288+ payload := backend .Payload ()
289+ require .NotNil (t , payload )
290+
291+ logs := payload .(transport.Logs )
292+ require .Len (t , logs .Logs , 1 )
293+
294+ assert .Equal (t , "" , logs .Logs [0 ].Tags )
295+ })
296+
297+ t .Run ("message without tags has empty tags field" , func (t * testing.T ) {
298+ backend := newLoggerBackend (10 )
299+ record := NewRecord (LogDebug , "plain message" )
300+ backend .Add (record ) // No WithTags option
301+
302+ payload := backend .Payload ()
303+ require .NotNil (t , payload )
304+
305+ logs := payload .(transport.Logs )
306+ require .Len (t , logs .Logs , 1 )
307+
308+ assert .Equal (t , "" , logs .Logs [0 ].Tags )
309+ })
310+
311+ t .Run ("single tag is serialized correctly" , func (t * testing.T ) {
312+ backend := newLoggerBackend (10 )
313+ record := NewRecord (LogDebug , "single tag message" )
314+ backend .Add (record , WithTags ([]string {"env:production" }))
315+
316+ payload := backend .Payload ()
317+ require .NotNil (t , payload )
318+
319+ logs := payload .(transport.Logs )
320+ require .Len (t , logs .Logs , 1 )
321+
322+ assert .Equal (t , "env:production" , logs .Logs [0 ].Tags )
323+ })
324+
325+ t .Run ("multiple WithTags options appends tags" , func (t * testing.T ) {
326+ backend := newLoggerBackend (10 )
327+ record := NewRecord (LogDebug , "multi tags message" )
328+ backend .Add (record ,
329+ WithTags ([]string {"product:appsec" }),
330+ WithTags ([]string {"version:1.0" , "env:prod" }),
331+ )
332+
333+ payload := backend .Payload ()
334+ require .NotNil (t , payload )
335+
336+ logs := payload .(transport.Logs )
337+ require .Len (t , logs .Logs , 1 )
338+
339+ // All tags from both WithTags calls should be present
340+ assert .Equal (t , "product:appsec,version:1.0,env:prod" , logs .Logs [0 ].Tags )
341+ })
342+
343+ t .Run ("multiple WithTags options deduplicates tags" , func (t * testing.T ) {
344+ backend := newLoggerBackend (10 )
345+ record := NewRecord (LogDebug , "dedup tags message" )
346+ backend .Add (record ,
347+ WithTags ([]string {"product:appsec" , "env:prod" }),
348+ WithTags ([]string {"version:1.0" , "product:appsec" }), // product:appsec is duplicated
349+ )
350+
351+ payload := backend .Payload ()
352+ require .NotNil (t , payload )
353+
354+ logs := payload .(transport.Logs )
355+ require .Len (t , logs .Logs , 1 )
356+
357+ // Tags should be deduplicated - product:appsec should appear only once
358+ assert .Equal (t , "product:appsec,env:prod,version:1.0" , logs .Logs [0 ].Tags )
359+ })
360+
361+ t .Run ("WithTags with empty slice after non-empty preserves original tags" , func (t * testing.T ) {
362+ backend := newLoggerBackend (10 )
363+ record := NewRecord (LogDebug , "preserve tags message" )
364+ backend .Add (record ,
365+ WithTags ([]string {"product:appsec" }),
366+ WithTags ([]string {}),
367+ )
368+
369+ payload := backend .Payload ()
370+ require .NotNil (t , payload )
371+
372+ logs := payload .(transport.Logs )
373+ require .Len (t , logs .Logs , 1 )
374+
375+ // Original tags should be preserved even when empty WithTags is added
376+ assert .Equal (t , "product:appsec" , logs .Logs [0 ].Tags )
377+ })
239378}
0 commit comments