@@ -18,10 +18,10 @@ package kamon
18
18
package trace
19
19
20
20
import java .time .{Duration , Instant }
21
-
22
21
import kamon .context .Context
23
22
import kamon .tag .TagSet
24
23
import kamon .trace .Span .Link
24
+ import kamon .trace .Span .Local ._logger
25
25
import kamon .trace .Trace .SamplingDecision
26
26
import kamon .util .Clock
27
27
import org .slf4j .LoggerFactory
@@ -77,6 +77,10 @@ sealed abstract class Span extends Sampler.Operation {
77
77
*/
78
78
def trace : Trace
79
79
80
+ /**
81
+ * Returns true if this Span was finished.
82
+ */
83
+
80
84
/**
81
85
* Returns true if this Span was initially created in another process and then transferred to this process.
82
86
*/
@@ -225,7 +229,7 @@ sealed abstract class Span extends Sampler.Operation {
225
229
226
230
}
227
231
228
- object Span {
232
+ object Span extends Configuration {
229
233
230
234
/**
231
235
* Key used to store and retrieve Span instances from the Context
@@ -417,6 +421,7 @@ object Span {
417
421
private var _trackMetrics : Boolean = initialTrackMetrics
418
422
private var _trackDelayedSpanMetrics : Boolean = true
419
423
private var _isOpen : Boolean = true
424
+ private var _debug : Boolean = config().getBoolean(" kamon.trace.debug" )
420
425
private var _hasError : Boolean = false
421
426
private var _operationName : String = initialOperationName
422
427
private var _marks : List [Mark ] = initialMarks
@@ -435,55 +440,81 @@ object Span {
435
440
_startedAt = at
436
441
_isDelayedStarted = true
437
442
mark(MarkKeys .SpanStarted , at)
438
- }
443
+ } else if (warnOnClosed)
444
+ _logger.warn(s " Cannot start finished span with name: ${_operationName}" )
439
445
this
440
446
}
441
447
442
448
override def tag (key : String , value : String ): Span = synchronized {
443
- if (isSampled && _isOpen)
449
+ if (isSampled && _isOpen) {
444
450
_spanTags.add(key, value)
451
+ } else if (warnOnClosed) {
452
+ _logger.warn(s " Cannot apply tag: Tag( ${key}, ${value}) to finished span with name: ${_operationName}" )
453
+ }
445
454
this
446
455
}
447
456
448
457
override def tag (key : String , value : Long ): Span = synchronized {
449
- if (isSampled && _isOpen)
458
+ if (isSampled && _isOpen) {
450
459
_spanTags.add(key, value)
460
+ } else if (warnOnClosed) {
461
+ _logger.warn(s " Cannot apply tag: Tag( ${key}, ${value}) to finished span with name: ${_operationName}" )
462
+ }
451
463
this
452
464
}
453
465
454
466
override def tag (key : String , value : Boolean ): Span = synchronized {
455
- if (isSampled && _isOpen)
467
+ if (isSampled && _isOpen) {
456
468
_spanTags.add(key, value)
469
+ } else if (warnOnClosed) {
470
+ _logger.warn(s " Cannot apply tag: Tag( ${key}, ${value}) to finished span with name: ${_operationName}" )
471
+ }
457
472
this
458
473
}
459
474
460
475
override def tag (tags : TagSet ): Span = synchronized {
461
- if (isSampled && _isOpen)
476
+ if (isSampled && _isOpen) {
462
477
_spanTags.add(tags)
478
+ } else if (warnOnClosed) {
479
+ _logger.warn(s " Cannot apply tags: ${tags} to finished span with name: ${_operationName}" )
480
+ }
463
481
this
464
482
}
465
483
466
484
override def tagMetrics (key : String , value : String ): Span = synchronized {
467
- if (_isOpen && _trackMetrics)
485
+ if (_isOpen && _trackMetrics) {
468
486
_metricTags.add(key, value)
487
+ } else if (warnOnClosed) {
488
+ _logger.warn(s " Cannot apply metric: Metric( ${key}, ${value}) to finished span with name: ${_operationName}" )
489
+ }
469
490
this
470
491
}
471
492
472
493
override def tagMetrics (key : String , value : Long ): Span = synchronized {
473
- if (_isOpen && _trackMetrics)
494
+ if (_isOpen && _trackMetrics) {
474
495
_metricTags.add(key, value)
475
- this
496
+ } else if (warnOnClosed) {
497
+ _logger.warn(s " Cannot apply metric: Metric( ${key}, ${value}) to finished span with name: ${_operationName}" )
498
+ }
499
+ this
476
500
}
477
501
478
502
override def tagMetrics (key : String , value : Boolean ): Span = synchronized {
479
- if (_isOpen && _trackMetrics)
503
+ if (_isOpen && _trackMetrics) {
480
504
_metricTags.add(key, value)
505
+ } else if (warnOnClosed) {
506
+ _logger.warn(s " Cannot apply metric: Metric( ${key}, ${value}) to finished span with name: ${_operationName}" )
507
+ }
508
+
481
509
this
482
510
}
483
511
484
512
override def tagMetrics (tags : TagSet ): Span = synchronized {
485
- if (_isOpen && _trackMetrics)
513
+ if (_isOpen && _trackMetrics) {
486
514
_metricTags.add(tags)
515
+ } else if (warnOnClosed) {
516
+ _logger.warn(s " Cannot apply tag metrics: ${tags} to finished span with name: ${_operationName}" )
517
+ }
487
518
this
488
519
}
489
520
@@ -492,14 +523,21 @@ object Span {
492
523
}
493
524
494
525
override def mark (key : String , at : Instant ): Span = synchronized {
495
- if (_isOpen)
526
+ if (_isOpen) {
496
527
_marks = Mark (at, key) :: _marks
528
+ } else if (warnOnClosed) {
529
+ _logger.warn(s " Cannot apply mark: Mark( ${key}, ${at}) to finished span with name: ${_operationName}" )
530
+ }
497
531
this
498
532
}
499
533
500
534
override def link (span : Span , kind : Link .Kind ): Span = synchronized {
501
- if (_isOpen)
535
+ if (_isOpen) {
502
536
_links = Link (kind, span.trace, span.id) :: _links
537
+ } else if (warnOnClosed) {
538
+ _logger.warn(s " Cannot link span ${span.operationName()} to finished span with name: ${_operationName}" )
539
+ }
540
+
503
541
this
504
542
}
505
543
@@ -509,6 +547,8 @@ object Span {
509
547
510
548
if (isSampled)
511
549
_spanTags.add(TagKeys .ErrorMessage , message)
550
+ } else if (warnOnClosed) {
551
+ _logger.warn(s " Cannot fail finished span with name: ${_operationName}" )
512
552
}
513
553
this
514
554
}
@@ -523,6 +563,8 @@ object Span {
523
563
if (includeErrorStacktrace)
524
564
_spanTags.add(TagKeys .ErrorStacktrace , toStackTraceString(throwable))
525
565
}
566
+ } else if (warnOnClosed) {
567
+ _logger.warn(s " Cannot fail finished span with name: ${_operationName}" )
526
568
}
527
569
this
528
570
}
@@ -537,7 +579,10 @@ object Span {
537
579
if (includeErrorStacktrace)
538
580
_spanTags.add(TagKeys .ErrorStacktrace , toStackTraceString(throwable))
539
581
}
582
+ } else if (warnOnClosed) {
583
+ _logger.warn(s " Cannot fail finished span with name: ${_operationName}" )
540
584
}
585
+
541
586
this
542
587
}
543
588
@@ -578,8 +623,12 @@ object Span {
578
623
}
579
624
580
625
override def name (operationName : String ): Span = synchronized {
581
- if (_isOpen)
626
+ if (_isOpen) {
582
627
_operationName = operationName
628
+ } else if (warnOnClosed) {
629
+ _logger.warn(s " Cannot name finished span with name: ${_operationName}" )
630
+ }
631
+
583
632
this
584
633
}
585
634
@@ -608,7 +657,14 @@ object Span {
608
657
val finalMetricTags = createMetricTags()
609
658
recordSpanMetrics(finishedAt, finalMetricTags)
610
659
reportSpan(finishedAt, finalMetricTags)
660
+ } else if (warnOnClosed) {
661
+ _logger.warn(s " Cannot finish already finished span with name: ${_operationName}" )
611
662
}
663
+
664
+ }
665
+
666
+ private def warnOnClosed = {
667
+ _debug && ! _isOpen
612
668
}
613
669
614
670
private def isSampled : Boolean =
@@ -667,7 +723,6 @@ object Span {
667
723
object Local {
668
724
private val _logger = LoggerFactory .getLogger(classOf [Span .Local ])
669
725
}
670
-
671
726
/**
672
727
* A immutable, no-op Span that can be used to signal that there is no Span information. An empty Span completely
673
728
* ignores all writes made to it.
@@ -680,29 +735,38 @@ object Span {
680
735
override def isRemote : Boolean = false
681
736
override def isEmpty : Boolean = true
682
737
override def position (): Position = Position .Unknown
683
- override def tag (key : String , value : String ): Span = this
684
- override def tag (key : String , value : Long ): Span = this
685
- override def tag (key : String , value : Boolean ): Span = this
686
- override def tag (tagSet : TagSet ): Span = this
687
- override def tagMetrics (key : String , value : String ): Span = this
688
- override def tagMetrics (key : String , value : Long ): Span = this
689
- override def tagMetrics (key : String , value : Boolean ): Span = this
690
- override def tagMetrics (tagSet : TagSet ): Span = this
691
- override def mark (key : String ): Span = this
692
- override def mark (key : String , at : Instant ): Span = this
693
- override def link (span : Span , kind : Link .Kind ): Span = this
694
- override def fail (errorMessage : String ): Span = this
695
- override def fail (cause : Throwable ): Span = this
696
- override def fail (errorMessage : String , cause : Throwable ): Span = this
697
- override def name (name : String ): Span = this
738
+ override def tag (key : String , value : String ): Span = warnAndDiscard()
739
+ override def tag (key : String , value : Long ): Span = warnAndDiscard()
740
+ override def tag (key : String , value : Boolean ): Span = warnAndDiscard()
741
+ override def tag (tagSet : TagSet ): Span = warnAndDiscard()
742
+ override def tagMetrics (key : String , value : String ): Span = warnAndDiscard()
743
+ override def tagMetrics (key : String , value : Long ): Span = warnAndDiscard()
744
+ override def tagMetrics (key : String , value : Boolean ): Span = warnAndDiscard()
745
+ override def tagMetrics (tagSet : TagSet ): Span = warnAndDiscard()
746
+ override def mark (key : String ): Span = warnAndDiscard()
747
+ override def mark (key : String , at : Instant ): Span = warnAndDiscard()
748
+ override def link (span : Span , kind : Link .Kind ): Span = warnAndDiscard()
749
+ override def fail (errorMessage : String ): Span = warnAndDiscard()
750
+ override def fail (cause : Throwable ): Span = warnAndDiscard()
751
+ override def fail (errorMessage : String , cause : Throwable ): Span = warnAndDiscard()
752
+ override def name (name : String ): Span = warnAndDiscard()
698
753
override def trackMetrics (): Span = this
699
754
override def doNotTrackMetrics (): Span = this
700
755
override def takeSamplingDecision (): Span = this
701
- override def finish (): Unit = {}
702
- override def finish (at : Instant ): Unit = {}
703
- override def finishAfter (duration : Duration ): Unit = {}
756
+ override def finish (): Unit = { warnAndDiscard(); {} }
757
+ override def finish (at : Instant ): Unit = { warnAndDiscard(); {} }
758
+ override def finishAfter (duration : Duration ): Unit = { warnAndDiscard(); {} }
704
759
override def operationName (): String = " empty"
705
760
override def toString (): String = " Span.Empty"
761
+
762
+ private val _logger = LoggerFactory .getLogger(classOf [Span ])
763
+ private def _debug : Boolean = config().getBoolean(" kamon.trace.debug" )
764
+ private def warnAndDiscard (): Span = {
765
+ if (_debug) {
766
+ _logger.debug(" Cannot perform operations on Empty spans." )
767
+ }
768
+ this
769
+ }
706
770
}
707
771
708
772
@@ -716,29 +780,38 @@ object Span {
716
780
override def isRemote : Boolean = true
717
781
override def isEmpty : Boolean = false
718
782
override def position (): Position = Position .Unknown
719
- override def tag (key : String , value : String ): Span = this
720
- override def tag (key : String , value : Long ): Span = this
721
- override def tag (key : String , value : Boolean ): Span = this
722
- override def tag (tagSet : TagSet ): Span = this
723
- override def tagMetrics (key : String , value : String ): Span = this
724
- override def tagMetrics (key : String , value : Long ): Span = this
725
- override def tagMetrics (key : String , value : Boolean ): Span = this
726
- override def tagMetrics (tagSet : TagSet ): Span = this
727
- override def mark (key : String ): Span = this
728
- override def mark (key : String , at : Instant ): Span = this
729
- override def link (span : Span , kind : Link .Kind ): Span = this
730
- override def fail (errorMessage : String ): Span = this
731
- override def fail (cause : Throwable ): Span = this
732
- override def fail (errorMessage : String , cause : Throwable ): Span = this
733
- override def name (name : String ): Span = this
783
+ override def tag (key : String , value : String ): Span = warnAndDiscard()
784
+ override def tag (key : String , value : Long ): Span = warnAndDiscard()
785
+ override def tag (key : String , value : Boolean ): Span = warnAndDiscard()
786
+ override def tag (tagSet : TagSet ): Span = warnAndDiscard()
787
+ override def tagMetrics (key : String , value : String ): Span = warnAndDiscard()
788
+ override def tagMetrics (key : String , value : Long ): Span = warnAndDiscard()
789
+ override def tagMetrics (key : String , value : Boolean ): Span = warnAndDiscard()
790
+ override def tagMetrics (tagSet : TagSet ): Span = warnAndDiscard()
791
+ override def mark (key : String ): Span = warnAndDiscard()
792
+ override def mark (key : String , at : Instant ): Span = warnAndDiscard()
793
+ override def link (span : Span , kind : Link .Kind ): Span = warnAndDiscard()
794
+ override def fail (errorMessage : String ): Span = warnAndDiscard()
795
+ override def fail (cause : Throwable ): Span = warnAndDiscard()
796
+ override def fail (errorMessage : String , cause : Throwable ): Span = warnAndDiscard()
797
+ override def name (name : String ): Span = warnAndDiscard()
734
798
override def trackMetrics (): Span = this
735
799
override def doNotTrackMetrics (): Span = this
736
800
override def takeSamplingDecision (): Span = this
737
- override def finish (): Unit = {}
738
- override def finish (at : Instant ): Unit = {}
739
- override def finishAfter (duration : Duration ): Unit = {}
801
+ override def finish (): Unit = { warnAndDiscard(); {} }
802
+ override def finish (at : Instant ): Unit = { warnAndDiscard(); {} }
803
+ override def finishAfter (duration : Duration ): Unit = { warnAndDiscard(); {} }
740
804
override def operationName (): String = " empty"
741
805
override def toString (): String = s " Span.Remote{id= ${id.string},parentId= ${parentId.string},trace= ${trace}"
806
+
807
+ private val _logger = LoggerFactory .getLogger(classOf [Span .Remote ])
808
+ private def _debug : Boolean = config().getBoolean(" kamon.trace.debug" )
809
+ private def warnAndDiscard (): Span = {
810
+ if (_debug) {
811
+ _logger.debug(" Cannot perform operations on Remote spans." )
812
+ }
813
+ this
814
+ }
742
815
}
743
816
744
817
0 commit comments