21
21
#include "memfault/core/math.h"
22
22
#include "memfault/core/platform/debug_log.h"
23
23
#include "memfault/core/platform/overrides.h"
24
+ #include "memfault/core/platform/system_time.h"
24
25
#include "memfault/core/sdk_assert.h"
25
26
#include "memfault/util/base64.h"
26
27
#include "memfault/util/circular_buffer.h"
@@ -97,15 +98,17 @@ bool memfault_log_get_regions(sMemfaultLogRegions *regions) {
97
98
return true;
98
99
}
99
100
100
- static uint8_t prv_build_header (eMemfaultPlatformLogLevel level , eMemfaultLogRecordType type ) {
101
+ static uint8_t prv_build_header (eMemfaultPlatformLogLevel level , eMemfaultLogRecordType type ,
102
+ bool timestamped ) {
101
103
MEMFAULT_STATIC_ASSERT (kMemfaultPlatformLogLevel_NumLevels <= 8 ,
102
104
"Number of log levels exceed max number that log module can track" );
103
105
MEMFAULT_STATIC_ASSERT (kMemfaultLogRecordType_NumTypes <= 2 ,
104
106
"Number of log types exceed max number that log module can track" );
105
107
106
108
const uint8_t level_field = (level << MEMFAULT_LOG_HDR_LEVEL_POS ) & MEMFAULT_LOG_HDR_LEVEL_MASK ;
107
109
const uint8_t type_field = (type << MEMFAULT_LOG_HDR_TYPE_POS ) & MEMFAULT_LOG_HDR_TYPE_MASK ;
108
- return level_field | type_field ;
110
+ const uint8_t timestamped_field = timestamped ? MEMFAULT_LOG_HDR_TIMESTAMPED_MASK : 0 ;
111
+ return level_field | type_field | timestamped_field ;
109
112
}
110
113
111
114
void memfault_log_set_min_save_level (eMemfaultPlatformLogLevel min_log_level ) {
@@ -225,10 +228,21 @@ static bool prv_read_log_iter_callback(sMfltLogIterator *iter) {
225
228
return false;
226
229
}
227
230
228
- ctx -> log -> msg [iter -> entry .len ] = '\0' ;
229
231
ctx -> log -> level = memfault_log_get_level_from_hdr (iter -> entry .hdr );
230
232
ctx -> log -> type = memfault_log_get_type_from_hdr (iter -> entry .hdr );
231
233
ctx -> log -> msg_len = iter -> entry .len ;
234
+ #if MEMFAULT_LOG_TIMESTAMPS_ENABLE
235
+ const size_t timestamp_len = sizeof (ctx -> log -> timestamp );
236
+ if (memfault_log_hdr_is_timestamped (iter -> entry .hdr ) && (iter -> entry .len >= timestamp_len )) {
237
+ memcpy (& ctx -> log -> timestamp , ctx -> log -> msg , timestamp_len );
238
+ // shift the message over to remove the timestamp
239
+ memmove (ctx -> log -> msg , & ctx -> log -> msg [timestamp_len ], ctx -> log -> msg_len - timestamp_len );
240
+ ctx -> log -> msg_len -= timestamp_len ;
241
+ } else {
242
+ ctx -> log -> timestamp = 0 ;
243
+ }
244
+ #endif
245
+ ctx -> log -> msg [ctx -> log -> msg_len ] = '\0' ;
232
246
ctx -> has_log = true;
233
247
return false;
234
248
}
@@ -402,8 +416,25 @@ static void prv_log_save(eMemfaultPlatformLogLevel level, const void *log, size_
402
416
}
403
417
404
418
bool log_written = false;
405
- const size_t truncated_log_len = MEMFAULT_MIN (log_len , MEMFAULT_LOG_MAX_LINE_SAVE_LEN );
406
- const size_t bytes_needed = sizeof (sMfltRamLogEntry ) + truncated_log_len ;
419
+ #if MEMFAULT_LOG_TIMESTAMPS_ENABLE
420
+ sMemfaultCurrentTime timestamp ;
421
+ const bool timestamped = memfault_platform_time_get_current (& timestamp );
422
+ uint32_t timestamp_val ; // forward declaration for sizeof()
423
+ const size_t timestamped_len = timestamped ? sizeof (timestamp_val ) : 0 ;
424
+ #else
425
+ const bool timestamped = false;
426
+ const size_t timestamped_len = 0 ;
427
+ #endif
428
+
429
+ // maximum msg length is truncated by timestamp, when enabled and valid.
430
+ const size_t max_log_msg_len = MEMFAULT_LOG_MAX_LINE_SAVE_LEN - timestamped_len ;
431
+
432
+ const size_t truncated_log_len = MEMFAULT_MIN (log_len , max_log_msg_len );
433
+ // total log length for the log entry .len field includes the timestamp.
434
+ const uint8_t total_log_len = (uint8_t )(truncated_log_len + timestamped_len );
435
+ // circular buffer space needed includes the metadata (hdr + len) and msg
436
+ const size_t bytes_needed = sizeof (sMfltRamLogEntry ) + total_log_len ;
437
+
407
438
if (should_lock ) {
408
439
memfault_lock ();
409
440
}
@@ -413,10 +444,16 @@ static void prv_log_save(eMemfaultPlatformLogLevel level, const void *log, size_
413
444
if (space_free ) {
414
445
s_memfault_ram_logger .recorded_msg_count ++ ;
415
446
sMfltRamLogEntry entry = {
416
- .len = ( uint8_t ) truncated_log_len ,
417
- .hdr = prv_build_header ( level , log_type ) ,
447
+ .hdr = prv_build_header ( level , log_type , timestamped ) ,
448
+ .len = total_log_len ,
418
449
};
419
450
memfault_circular_buffer_write (circ_bufp , & entry , sizeof (entry ));
451
+ #if MEMFAULT_LOG_TIMESTAMPS_ENABLE
452
+ if (timestamped ) {
453
+ timestamp_val = timestamp .info .unix_timestamp_secs ;
454
+ memfault_circular_buffer_write (circ_bufp , & timestamp_val , sizeof (timestamp_val ));
455
+ }
456
+ #endif
420
457
memfault_circular_buffer_write (circ_bufp , log , truncated_log_len );
421
458
log_written = true;
422
459
} else {
0 commit comments