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