1010use OpenTelemetry \API \Instrumentation \CachedInstrumentation ;
1111use OpenTelemetry \API \Logs \LogRecord ;
1212use OpenTelemetry \API \Logs \Severity ;
13+ use OpenTelemetry \SDK \Common \Exception \StackTraceFormatter ;
14+ use Throwable ;
1315use TypeError ;
1416
1517class LogWatcher extends Watcher
@@ -52,8 +54,21 @@ public function recordLog(MessageLogged $log): void
5254 // Should this fail, we should continue to emit the LogRecord.
5355 }
5456
57+ $ contextToEncode = array_filter ($ log ->context );
58+
59+ $ exception = $ this ->getExceptionFromContext ($ log ->context );
60+
61+ if ($ exception !== null ) {
62+ unset($ contextToEncode ['exception ' ]);
63+ }
64+
5565 $ attributes = [
56- 'context ' => json_encode (array_filter ($ log ->context )),
66+ 'context ' => json_encode ($ contextToEncode ),
67+ ...$ exception !== null ? [
68+ 'exception.type ' => $ exception ::class,
69+ 'exception.message ' => $ exception ->getMessage (),
70+ 'exception.stacktrace ' => StackTraceFormatter::format ($ exception ),
71+ ] : [],
5772 ];
5873
5974 $ logger = $ this ->instrumentation ->logger ();
@@ -65,4 +80,16 @@ public function recordLog(MessageLogged $log): void
6580
6681 $ logger ->emit ($ record );
6782 }
83+
84+ private function getExceptionFromContext (array $ context ): ?Throwable
85+ {
86+ if (
87+ ! isset ($ context ['exception ' ]) ||
88+ ! $ context ['exception ' ] instanceof Throwable
89+ ) {
90+ return null ;
91+ }
92+
93+ return $ context ['exception ' ];
94+ }
6895}
0 commit comments