@@ -25,6 +25,7 @@ var os = require('os');
25
25
var fs = require ( 'fs' ) ;
26
26
var util = require ( 'util' ) ;
27
27
var assert = require ( 'assert' ) ;
28
+ var dtrace = require ( 'dtrace-provider' ) ;
28
29
var EventEmitter = require ( 'events' ) . EventEmitter ;
29
30
30
31
@@ -156,6 +157,8 @@ var levelFromName = {
156
157
'fatal' : FATAL
157
158
} ;
158
159
160
+ var dtp = undefined ;
161
+ var probes = { } ;
159
162
160
163
/**
161
164
* Resolve a level number, name (upper or lowercase) to a level number value.
@@ -299,6 +302,22 @@ function Logger(options, _childOptions, _childSimple) {
299
302
this . fields = { } ;
300
303
}
301
304
305
+ if ( ! dtp ) {
306
+ dtp = dtrace . createDTraceProvider ( 'bunyan' ) ;
307
+
308
+ for ( var level in levelFromName ) {
309
+ var probe ;
310
+
311
+ probes [ levelFromName [ level ] ] = probe =
312
+ dtp . addProbe ( 'log-' + level , 'char *' ) ;
313
+
314
+ // Explicitly add a reference to dtp to prevent it from being GC'd
315
+ probe . dtp = dtp ;
316
+ }
317
+
318
+ dtp . enable ( ) ;
319
+ }
320
+
302
321
// Helpers
303
322
function addStream ( s ) {
304
323
s = objCopy ( s ) ;
@@ -641,8 +660,9 @@ Logger.prototype._mkRecord = function (fields, level, msgArgs) {
641
660
* Emit a log record.
642
661
*
643
662
* @param rec {log record}
663
+ * @param noemit {Boolean} Optional. Set to true to only return the string.
644
664
*/
645
- Logger . prototype . _emit = function ( rec ) {
665
+ Logger . prototype . _emit = function ( rec , noemit ) {
646
666
var i ;
647
667
648
668
var obj = objCopy ( rec [ 0 ] ) ;
@@ -685,6 +705,9 @@ Logger.prototype._emit = function (rec) {
685
705
str = JSON . stringify ( obj , safeCycles ( ) ) + '\n' ;
686
706
}
687
707
708
+ if ( noemit )
709
+ return str ;
710
+
688
711
for ( i = 0 ; i < this . streams . length ; i ++ ) {
689
712
var s = this . streams [ i ] ;
690
713
if ( s . level <= level ) {
@@ -693,6 +716,8 @@ Logger.prototype._emit = function (rec) {
693
716
s . stream . write ( s . raw ? obj : str ) ;
694
717
}
695
718
} ;
719
+
720
+ return str ;
696
721
}
697
722
698
723
@@ -702,33 +727,50 @@ Logger.prototype._emit = function (rec) {
702
727
*/
703
728
function mkLogEmitter ( minLevel ) {
704
729
return function ( ) {
730
+ var log = this ;
731
+
732
+ var mkRecord = function ( args ) {
733
+ if ( args [ 0 ] instanceof Error ) {
734
+ // `log.<level>(err, ...)`
735
+ fields = { err : errSerializer ( args [ 0 ] ) } ;
736
+ if ( args . length === 1 ) {
737
+ msgArgs = [ fields . err . message ] ;
738
+ } else {
739
+ msgArgs = Array . prototype . slice . call ( args , 1 ) ;
740
+ }
741
+ } else if ( typeof ( args [ 0 ] ) === 'string' ) { // `log.<level>(msg, ...)`
742
+ fields = null ;
743
+ msgArgs = Array . prototype . slice . call ( args ) ;
744
+ } else if ( Buffer . isBuffer ( args [ 0 ] ) ) { // `log.<level>(buf, ...)`
745
+ // Almost certainly an error, show `inspect(buf)`. See bunyan issue #35.
746
+ fields = null ;
747
+ msgArgs = Array . prototype . slice . call ( args ) ;
748
+ msgArgs [ 0 ] = util . inspect ( msgArgs [ 0 ] ) ;
749
+ } else { // `log.<level>(fields, msg, ...)`
750
+ fields = args [ 0 ] ;
751
+ msgArgs = Array . prototype . slice . call ( args , 1 ) ;
752
+ }
753
+ return log . _mkRecord ( fields , minLevel , msgArgs ) ;
754
+ } ;
755
+
705
756
var fields = null , msgArgs = null ;
706
757
if ( arguments . length === 0 ) { // `log.<level>()`
707
758
return ( this . _level <= minLevel ) ;
708
759
} else if ( this . _level > minLevel ) {
709
- return ;
710
- } else if ( arguments [ 0 ] instanceof Error ) {
711
- // `log.<level>(err, ...)`
712
- fields = { err : errSerializer ( arguments [ 0 ] ) } ;
713
- if ( arguments . length === 1 ) {
714
- msgArgs = [ fields . err . message ] ;
715
- } else {
716
- msgArgs = Array . prototype . slice . call ( arguments , 1 ) ;
717
- }
718
- } else if ( typeof ( arguments [ 0 ] ) === 'string' ) { // `log.<level>(msg, ...)`
719
- fields = null ;
720
- msgArgs = Array . prototype . slice . call ( arguments ) ;
721
- } else if ( Buffer . isBuffer ( arguments [ 0 ] ) ) { // `log.<level>(buf, ...)`
722
- // Almost certainly an error, show `inspect(buf)`. See bunyan issue #35.
723
- fields = null ;
724
- msgArgs = Array . prototype . slice . call ( arguments ) ;
725
- msgArgs [ 0 ] = util . inspect ( msgArgs [ 0 ] ) ;
726
- } else { // `log.<level>(fields, msg, ...)`
727
- fields = arguments [ 0 ] ;
728
- msgArgs = Array . prototype . slice . call ( arguments , 1 ) ;
760
+ /*
761
+ * Even if our level is such that we will not emit the record, we want
762
+ * to fire the DTrace probe associated with the level -- but we only
763
+ * assemble the string representation if the probe is in fact enabled.
764
+ */
765
+ msgArgs = arguments ;
766
+
767
+ probes [ minLevel ] . fire ( function ( ) {
768
+ return [ log . _emit ( mkRecord ( msgArgs ) , true ) ] ;
769
+ } ) ;
770
+ } else {
771
+ var str = this . _emit ( mkRecord ( arguments ) ) ;
772
+ probes [ minLevel ] . fire ( function ( ) { return [ str ] ; } ) ;
729
773
}
730
- var rec = this . _mkRecord ( fields , minLevel , msgArgs ) ;
731
- this . _emit ( rec ) ;
732
774
}
733
775
}
734
776
0 commit comments