33require_once ('vendor/autoload.php ' );
44
55use Monolog \Logger ;
6- use Monolog \Handler \StreamHandler as MonologStreamHandler ;
6+ use Monolog \Handler \StreamHandler ;
77
88/*
99 Level of logs we use:
@@ -30,15 +30,42 @@ class BuffLog {
3030 "CRITICAL " => Logger::CRITICAL
3131 ];
3232
33+ protected static $ instance ;
34+
35+ /**
36+ * Method to return the Monolog instance
37+ *
38+ * @return \Monolog\Logger
39+ */
40+ static public function getLogger ()
41+ {
42+ if (! self ::$ instance ) {
43+ self ::configureInstance ();
44+ }
45+ return self ::$ instance ;
46+ }
47+
48+ protected static function configureInstance ()
49+ {
50+ // @TODO: We could potentially use the Kubernetes downward API to
51+ // define the logger name. This will make it easier for developers
52+ // to read and friendlier to identify where come the logs at a glance
53+ $ logger = new Logger ('php-bufflog ' );
54+ $ handler = new StreamHandler ('php://stdout ' );
55+ $ handler ->setFormatter ( new \Monolog \Formatter \JsonFormatter () );
56+ $ logger ->pushHandler ($ handler );
57+
58+ self ::$ instance = $ logger ;
59+ }
60+
3361 public static function debug ($ message , $ context = [])
3462 {
3563 self ::setVerbosity ();
3664 if (self ::$ currentVerbosity > Logger::DEBUG ) {
3765 return ;
3866 }
39-
40- $ logOutput = self ::formatLog ($ message , Logger::DEBUG , $ context );
41- self ::getLogger ()->debug ($ logOutput );
67+ self ::processLog ();
68+ self ::getLogger ()->addDebug ($ message , $ context );
4269 }
4370
4471 public static function info ($ message , $ context = [])
@@ -48,8 +75,8 @@ public static function info($message, $context = [])
4875 return ;
4976 }
5077
51- $ logOutput = self ::formatLog ( $ message , Logger:: INFO , $ context );
52- self ::getLogger ()->info ( $ logOutput );
78+ self ::processLog ( );
79+ self ::getLogger ()->addInfo ( $ message , $ context );
5380 }
5481
5582 public static function warning ($ message , $ context = [])
@@ -59,8 +86,8 @@ public static function warning($message, $context = [])
5986 return ;
6087 }
6188
62- $ logOutput = self ::formatLog ( $ message , Logger:: WARNING , $ context );
63- self ::getLogger ()->warn ( $ logOutput );
89+ self ::processLog ( );
90+ self ::getLogger ()->addWarning ( $ message , $ context );
6491 }
6592
6693 public static function error ($ message , $ context = [])
@@ -70,55 +97,51 @@ public static function error($message, $context = [])
7097 return ;
7198 }
7299
73- $ logOutput = self ::formatLog ( $ message , Logger:: ERROR , $ context );
74- self ::getLogger ()->error ( $ logOutput );
100+ self ::processLog ( );
101+ self ::getLogger ()->addError ( $ message , $ context );
75102 }
76103
77104 // @TODO: That one might could also create an alert in Datadog?
78105 public static function critical ($ message , $ context = [])
79106 {
80107 self ::setVerbosity ();
81- $ logOutput = self ::formatLog ( $ message , Logger:: CRITICAL , $ context );
82- self ::getLogger ()->critical ( $ logOutput );
108+ self ::processLog ( );
109+ self ::getLogger ()->addCritical ( $ message , $ context );
83110 }
84111
85- private function formatLog ( $ message , $ level , $ context = [] )
112+ private function processLog ( )
86113 {
87- // Add traces information to logs to be able correlate with APM
88- $ ddTraceSpan = \DDTrace \GlobalTracer::get ()->getActiveSpan ();
89- $ context ['dd ' ] = [
90- "trace_id " => $ ddTraceSpan ->getTraceId (),
91- "span_id " => $ ddTraceSpan ->getSpanId ()
92- ];
93-
94- $ output = [
95- "message " => $ message ,
96- "level " => $ level ,
97- "datetime " => date (\DateTime::ATOM ),
98- // we could use timestamp if we need ms precision (but it isn't readable) https://docs.datadoghq.com/logs/processing/#reserved-attributes
99- // 'timestamp' => round(microtime(true) * 1000),
100- "context " => $ context
101- ];
114+ // This should probably implemented as a Monolog Processor
115+ // https://github.com/Seldaek/monolog/tree/master/src/Monolog/Processor
116+ $ self ::getLogger ()->pushProcessor (function ($ record ) {
117+
118+ // We should grab any Buffer information useful when available
119+ // Need to check with the Core team: accountID / userID / profileID
120+ // $user = Buffer/Core::getCurrentUser();
121+ // That should look like:
122+ // $record['context']['user'] = array(
123+ // 'accountID' => $user->getAccountID(),
124+ // 'userID' => $user->getUserID(),
125+ // 'profileID' => $user->getProfileID()
126+ // );
127+
128+ // Add traces information to logs to be able correlate with APM
129+ $ ddTraceSpan = \DDTrace \GlobalTracer::get ()->getActiveSpan ();
130+ $ record ['context ' ]['dd ' ] = [
131+ "trace_id " => $ ddTraceSpan ->getTraceId (),
132+ "span_id " => $ ddTraceSpan ->getSpanId ()
133+ ];
134+ return $ record ;
135+ });
136+ }
102137
138+ private static function formatLog ()
139+ {
103140 try {
104141 $ output = json_encode ($ output , JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE );
105142 } catch (Exception $ e ) {
106143 error_log ("can't json_encode your message " );
107144 }
108-
109- return $ output ;
110- }
111-
112- private static function createLogger ()
113- {
114- // @TODO: We could potentially use the Kubernetes downward API to
115- // define the logger name. This will make it easier for developers
116- // to read and friendlier to identify where come the logs at a glance
117- self ::$ logger = new Logger ('php-bufflog ' );
118- $ handler = new MonologStreamHandler ('php://stdout ' );
119-
120- self ::$ logger ->pushHandler ($ handler );
121- return self ::$ logger ;
122145 }
123146
124147 private static function setVerbosity ()
@@ -129,14 +152,4 @@ private static function setVerbosity()
129152 }
130153 }
131154
132- public static function getLogger ()
133- {
134- if (!isset (self ::$ logger )) {
135- echo "Initializing logger \n" ;
136- self ::createLogger ();
137- }
138-
139- return self ::$ logger ;
140- }
141-
142155}
0 commit comments