1515#include "errno.h"
1616#include <unistd.h>
1717#include <sys/socket.h>
18+ #include <sys/time.h>
1819#endif
1920
2021#include "julia.h"
@@ -812,6 +813,56 @@ JL_DLLEXPORT int jl_printf(uv_stream_t *s, const char *format, ...)
812813 return c ;
813814}
814815
816+ STATIC_INLINE void print_error_msg_as_json (char * buf ) JL_NOTSAFEPOINT
817+ {
818+ // Our telemetry on SPCS expects a JSON object per line
819+ // The following lines prepare the timestamp string and the JSON object
820+ struct timeval tv ;
821+ struct tm * tm_info ;
822+ char timestamp_buffer [50 ];
823+ // Get current time
824+ gettimeofday (& tv , NULL );
825+ tm_info = gmtime (& tv .tv_sec );
826+ // Format time
827+ int offset = strftime (timestamp_buffer , 25 , "%Y-%m-%dT%H:%M:%S" , tm_info );
828+ // Append milliseconds
829+ snprintf (timestamp_buffer + offset , 25 , ".%03d" , tv .tv_usec / 1000 );
830+ const char * json_preamble_p1 = "\n{\"level\":\"Error\", \"timestamp\":\"" ;
831+ const char * json_preamble_p2 = "\", \"message\": \"" ;
832+ const char * json_postamble = "\"}\n" ;
833+ // Ignore write failures because there is nothing we can do
834+ write (jl_sig_fd , json_preamble_p1 , strlen (json_preamble_p1 ));
835+ write (jl_sig_fd , timestamp_buffer , strlen (timestamp_buffer ));
836+ write (jl_sig_fd , json_preamble_p2 , strlen (json_preamble_p2 ));
837+ // JSON escape the input string
838+ for (size_t i = 0 ; i < strlen (buf ); i += 1 ) {
839+ switch (buf [i ]) {
840+ case '"' :
841+ write (jl_sig_fd , "\\\"" , 2 );
842+ break ;
843+ case '\b' :
844+ write (jl_sig_fd , "\\b" , 2 );
845+ break ;
846+ case '\n' :
847+ write (jl_sig_fd , "\\n" , 2 );
848+ break ;
849+ case '\r' :
850+ write (jl_sig_fd , "\\r" , 2 );
851+ break ;
852+ case '\t' :
853+ write (jl_sig_fd , "\\t" , 2 );
854+ break ;
855+ case '\\' :
856+ write (jl_sig_fd , "\\\\" , 2 );
857+ break ;
858+ default :
859+ write (jl_sig_fd , buf + i , 1 );
860+ }
861+ }
862+ write (jl_sig_fd , json_postamble , strlen (json_postamble ));
863+ fdatasync (jl_sig_fd );
864+ }
865+
815866JL_DLLEXPORT void jl_safe_printf (const char * fmt , ...)
816867{
817868 static char buf [1000 ];
@@ -828,6 +879,9 @@ JL_DLLEXPORT void jl_safe_printf(const char *fmt, ...)
828879 va_end (args );
829880
830881 buf [999 ] = '\0' ;
882+ if (jl_inside_signal_handler () && jl_sig_fd != 0 ) {
883+ print_error_msg_as_json (buf );
884+ }
831885 if (write (STDERR_FILENO , buf , strlen (buf )) < 0 ) {
832886 // nothing we can do; ignore the failure
833887 }
0 commit comments