@@ -52,19 +52,40 @@ JsonPrinter::parse_fields(const std::string &str, const shared_iemgr &iemgr)
5252void
5353JsonPrinter::parse_opts (const std::string &str)
5454{
55- std::vector<std::string> opt_names ;
55+ std::vector<std::string> opts ;
5656
5757 if (str.empty ()) {
5858 return ;
5959 }
6060
61- opt_names = string_split (str, " ," );
61+ opts = string_split (str, " ," );
6262
63- for (const std::string &opt_raw : opt_names ) {
63+ for (const std::string &opt_raw : opts ) {
6464 std::string opt = string_trim_copy (opt_raw);
65+ std::vector<std::string> opt_parts = string_split (opt, " =" , 2 );
66+ const std::string &opt_name = (opt_parts.size () >= 1 ) ? opt_parts[0 ] : " " ;
67+ const std::string &opt_value = (opt_parts.size () >= 2 ) ? opt_parts[1 ] : " " ;
6568
6669 if (strcasecmp (opt.c_str (), " no-biflow-split" ) == 0 ) {
6770 m_biflow_split = false ;
71+
72+ } else if (strcasecmp (opt_name.c_str (), " timestamp" ) == 0 ) {
73+ if (opt_value.empty ()) {
74+ throw std::invalid_argument (
75+ " JSON output: timestamp option is missing value"
76+ " , use 'timestamp=unix' or 'timestamp=formatted'" );
77+ }
78+
79+ if (opt_value == " unix" ) {
80+ m_format_timestamp = false ;
81+ } else if (opt_value == " formatted" ) {
82+ m_format_timestamp = true ;
83+ } else {
84+ throw std::invalid_argument (
85+ " JSON output: invalid timestamp option '" + opt_value + " '"
86+ " , use 'timestamp=unix' or 'timestamp=formatted'" );
87+ }
88+
6889 } else {
6990 throw std::invalid_argument (" JSON output: unknown option '" + opt + " '" );
7091 }
@@ -306,24 +327,45 @@ JsonPrinter::append_boolean(const fds_drec_field &field)
306327void
307328JsonPrinter::append_timestamp (const fds_drec_field &field)
308329{
309- char buffer[FDS_CONVERT_STRLEN_DATE];
310- int ret;
330+ if (m_format_timestamp) {
331+ // Convert to formatted string
332+ char buffer[FDS_CONVERT_STRLEN_DATE];
333+ int ret;
334+
335+ ret = fds_datetime2str_be (
336+ field.data ,
337+ field.size ,
338+ field.info ->def ->data_type ,
339+ buffer,
340+ sizeof (buffer),
341+ FDS_CONVERT_TF_MSEC_UTC);
342+ if (ret < 0 ) {
343+ append_invalid ();
344+ return ;
345+ }
311346
312- ret = fds_datetime2str_be (
313- field.data ,
314- field.size ,
315- field.info ->def ->data_type ,
316- buffer,
317- sizeof (buffer),
318- FDS_CONVERT_TF_MSEC_UTC);
319- if (ret < 0 ) {
320- append_invalid ();
321- return ;
322- }
347+ m_buffer.push_back (' "' );
348+ m_buffer.append (buffer);
349+ m_buffer.push_back (' "' );
323350
324- m_buffer.push_back (' "' );
325- m_buffer.append (buffer);
326- m_buffer.push_back (' "' );
351+
352+ } else {
353+ // Convert to UNIX timestamp (in milliseconds)
354+ uint64_t time;
355+ if (fds_get_datetime_lp_be (field.data , field.size , field.info ->def ->data_type , &time) != FDS_OK) {
356+ append_invalid ();
357+ return ;
358+ }
359+
360+ time = htobe64 (time); // Convert to network byte order and use fast libfds converter
361+ char buffer[32 ];
362+ if (fds_uint2str_be (&time, sizeof (time), buffer, sizeof (buffer)) < 0 ) {
363+ append_invalid ();
364+ return ;
365+ }
366+
367+ m_buffer.append (buffer);
368+ }
327369}
328370
329371void
0 commit comments