WPILibC++ 2024.1.1-beta-4
DataLog.h
Go to the documentation of this file.
1// Copyright (c) FIRST and other WPILib contributors.
2// Open Source Software; you can modify and/or share it under the terms of
3// the WPILib BSD license file in the root directory of this project.
4
5#pragma once
6
7#include <stdint.h>
8
9#ifdef __cplusplus
10#include <concepts>
11#include <functional>
12#include <initializer_list>
13#include <memory>
14#include <ranges>
15#include <span>
16#include <string>
17#include <string_view>
18#include <thread>
19#include <utility>
20#include <vector>
21#include <version>
22
23#include "wpi/DenseMap.h"
24#include "wpi/SmallVector.h"
25#include "wpi/StringMap.h"
27#include "wpi/mutex.h"
29#include "wpi/struct/Struct.h"
30#include "wpi/timestamp.h"
31#endif // __cplusplus
32
33/**
34 * A datalog string (for use with string array).
35 */
37 /** Contents. */
38 const char* str;
39
40 /** Length. */
41 size_t len;
42};
43
44#ifdef __cplusplus
45
46namespace wpi {
47class Logger;
48} // namespace wpi
49
50namespace wpi::log {
51
52namespace impl {
53
58};
59
60} // namespace impl
61
62/**
63 * A data log. The log file is created immediately upon construction with a
64 * temporary filename. The file may be renamed at any time using the
65 * SetFilename() function.
66 *
67 * The lifetime of the data log object must be longer than any data log entry
68 * objects that refer to it.
69 *
70 * The data log is periodically flushed to disk. It can also be explicitly
71 * flushed to disk by using the Flush() function.
72 *
73 * Finish() is needed only to indicate in the log that a particular entry is
74 * no longer being used (it releases the name to ID mapping). Finish() is not
75 * required to be called for data to be flushed to disk; entries in the log
76 * are written as Append() calls are being made. In fact, Finish() does not
77 * need to be called at all; this is helpful to avoid shutdown races where the
78 * DataLog object might be destroyed before other objects. It's often not a
79 * good idea to call Finish() from destructors for this reason.
80 *
81 * DataLog calls are thread safe. DataLog uses a typical multiple-supplier,
82 * single-consumer setup. Writes to the log are atomic, but there is no
83 * guaranteed order in the log when multiple threads are writing to it;
84 * whichever thread grabs the write mutex first will get written first.
85 * For this reason (as well as the fact that timestamps can be set to
86 * arbitrary values), records in the log are not guaranteed to be sorted by
87 * timestamp.
88 */
89class DataLog final {
90 public:
91 /**
92 * Construct a new Data Log. The log will be initially created with a
93 * temporary filename.
94 *
95 * @param dir directory to store the log
96 * @param filename filename to use; if none provided, a random filename is
97 * generated of the form "wpilog_{}.wpilog"
98 * @param period time between automatic flushes to disk, in seconds;
99 * this is a time/storage tradeoff
100 * @param extraHeader extra header data
101 */
102 explicit DataLog(std::string_view dir = "", std::string_view filename = "",
103 double period = 0.25, std::string_view extraHeader = "");
104
105 /**
106 * Construct a new Data Log. The log will be initially created with a
107 * temporary filename.
108 *
109 * @param msglog message logger (will be called from separate thread)
110 * @param dir directory to store the log
111 * @param filename filename to use; if none provided, a random filename is
112 * generated of the form "wpilog_{}.wpilog"
113 * @param period time between automatic flushes to disk, in seconds;
114 * this is a time/storage tradeoff
115 * @param extraHeader extra header data
116 */
117 explicit DataLog(wpi::Logger& msglog, std::string_view dir = "",
118 std::string_view filename = "", double period = 0.25,
119 std::string_view extraHeader = "");
120
121 /**
122 * Construct a new Data Log that passes its output to the provided function
123 * rather than a file. The write function will be called on a separate
124 * background thread and may block. The write function is called with an
125 * empty data array when the thread is terminating.
126 *
127 * @param write write function
128 * @param period time between automatic calls to write, in seconds;
129 * this is a time/storage tradeoff
130 * @param extraHeader extra header data
131 */
132 explicit DataLog(std::function<void(std::span<const uint8_t> data)> write,
133 double period = 0.25, std::string_view extraHeader = "");
134
135 /**
136 * Construct a new Data Log that passes its output to the provided function
137 * rather than a file. The write function will be called on a separate
138 * background thread and may block. The write function is called with an
139 * empty data array when the thread is terminating.
140 *
141 * @param msglog message logger (will be called from separate thread)
142 * @param write write function
143 * @param period time between automatic calls to write, in seconds;
144 * this is a time/storage tradeoff
145 * @param extraHeader extra header data
146 */
147 explicit DataLog(wpi::Logger& msglog,
148 std::function<void(std::span<const uint8_t> data)> write,
149 double period = 0.25, std::string_view extraHeader = "");
150
152 DataLog(const DataLog&) = delete;
153 DataLog& operator=(const DataLog&) = delete;
154 DataLog(DataLog&&) = delete;
155 DataLog& operator=(const DataLog&&) = delete;
156
157 /**
158 * Change log filename.
159 *
160 * @param filename filename
161 */
163
164 /**
165 * Explicitly flushes the log data to disk.
166 */
167 void Flush();
168
169 /**
170 * Pauses appending of data records to the log. While paused, no data records
171 * are saved (e.g. AppendX is a no-op). Has no effect on entry starts /
172 * finishes / metadata changes.
173 */
174 void Pause();
175
176 /**
177 * Resumes appending of data records to the log. If called after Stop(),
178 * opens a new file (with random name if SetFilename was not called after
179 * Stop()) and appends Start records and schema data values for all previously
180 * started entries and schemas.
181 */
182 void Resume();
183
184 /**
185 * Stops appending all records to the log, and closes the log file.
186 */
187 void Stop();
188
189 /**
190 * Returns whether there is a data schema already registered with the given
191 * name.
192 *
193 * @param name Name (the string passed as the data type for records using this
194 * schema)
195 * @return True if schema already registered
196 */
197 bool HasSchema(std::string_view name) const;
198
199 /**
200 * Registers a data schema. Data schemas provide information for how a
201 * certain data type string can be decoded. The type string of a data schema
202 * indicates the type of the schema itself (e.g. "protobuf" for protobuf
203 * schemas, "struct" for struct schemas, etc). In the data log, schemas are
204 * saved just like normal records, with the name being generated from the
205 * provided name: "/.schema/<name>". Duplicate calls to this function with
206 * the same name are silently ignored.
207 *
208 * @param name Name (the string passed as the data type for records using this
209 * schema)
210 * @param type Type of schema (e.g. "protobuf", "struct", etc)
211 * @param schema Schema data
212 * @param timestamp Time stamp (may be 0 to indicate now)
213 */
215 std::span<const uint8_t> schema, int64_t timestamp = 0);
216
217 /**
218 * Registers a data schema. Data schemas provide information for how a
219 * certain data type string can be decoded. The type string of a data schema
220 * indicates the type of the schema itself (e.g. "protobuf" for protobuf
221 * schemas, "struct" for struct schemas, etc). In the data log, schemas are
222 * saved just like normal records, with the name being generated from the
223 * provided name: "/.schema/<name>". Duplicate calls to this function with
224 * the same name are silently ignored.
225 *
226 * @param name Name (the string passed as the data type for records using this
227 * schema)
228 * @param type Type of schema (e.g. "protobuf", "struct", etc)
229 * @param schema Schema data
230 * @param timestamp Time stamp (may be 0 to indicate now)
231 */
233 std::string_view schema, int64_t timestamp = 0) {
234 AddSchema(
235 name, type,
236 std::span<const uint8_t>{
237 reinterpret_cast<const uint8_t*>(schema.data()), schema.size()},
238 timestamp);
239 }
240
241 /**
242 * Registers a protobuf schema. Duplicate calls to this function with the same
243 * name are silently ignored.
244 *
245 * @tparam T protobuf serializable type
246 * @param msg protobuf message
247 * @param timestamp Time stamp (0 to indicate now)
248 */
249 template <ProtobufSerializable T>
250 void AddProtobufSchema(ProtobufMessage<T>& msg, int64_t timestamp = 0) {
251 if (timestamp == 0) {
252 timestamp = Now();
253 }
255 [this](auto typeString) { return HasSchema(typeString); },
256 [this, timestamp](auto typeString, auto schema) {
257 AddSchema(typeString, "proto:FileDescriptorProto", schema, timestamp);
258 });
259 }
260
261 /**
262 * Registers a struct schema. Duplicate calls to this function with the same
263 * name are silently ignored.
264 *
265 * @tparam T struct serializable type
266 * @param timestamp Time stamp (0 to indicate now)
267 */
268 template <StructSerializable T>
269 void AddStructSchema(int64_t timestamp = 0) {
270 if (timestamp == 0) {
271 timestamp = Now();
272 }
273 ForEachStructSchema<T>([this, timestamp](auto typeString, auto schema) {
274 AddSchema(typeString, "structschema", schema, timestamp);
275 });
276 }
277
278 /**
279 * Start an entry. Duplicate names are allowed (with the same type), and
280 * result in the same index being returned (Start/Finish are reference
281 * counted). A duplicate name with a different type will result in an error
282 * message being printed to the console and 0 being returned (which will be
283 * ignored by the Append functions).
284 *
285 * @param name Name
286 * @param type Data type
287 * @param metadata Initial metadata (e.g. data properties)
288 * @param timestamp Time stamp (may be 0 to indicate now)
289 *
290 * @return Entry index
291 */
293 std::string_view metadata = {}, int64_t timestamp = 0);
294
295 /**
296 * Finish an entry.
297 *
298 * @param entry Entry index
299 * @param timestamp Time stamp (may be 0 to indicate now)
300 */
301 void Finish(int entry, int64_t timestamp = 0);
302
303 /**
304 * Updates the metadata for an entry.
305 *
306 * @param entry Entry index
307 * @param metadata New metadata for the entry
308 * @param timestamp Time stamp (may be 0 to indicate now)
309 */
310 void SetMetadata(int entry, std::string_view metadata, int64_t timestamp = 0);
311
312 /**
313 * Appends a raw record to the log.
314 *
315 * @param entry Entry index, as returned by Start()
316 * @param data Byte array to record
317 * @param timestamp Time stamp (may be 0 to indicate now)
318 */
319 void AppendRaw(int entry, std::span<const uint8_t> data, int64_t timestamp);
320
321 /**
322 * Appends a raw record to the log.
323 *
324 * @param entry Entry index, as returned by Start()
325 * @param data Byte array to record
326 * @param timestamp Time stamp (may be 0 to indicate now)
327 */
328 void AppendRaw2(int entry, std::span<const std::span<const uint8_t>> data,
329 int64_t timestamp);
330
331 /**
332 * Appends a boolean record to the log.
333 *
334 * @param entry Entry index, as returned by Start()
335 * @param value Boolean value to record
336 * @param timestamp Time stamp (may be 0 to indicate now)
337 */
338 void AppendBoolean(int entry, bool value, int64_t timestamp);
339
340 /**
341 * Appends an integer record to the log.
342 *
343 * @param entry Entry index, as returned by Start()
344 * @param value Integer value to record
345 * @param timestamp Time stamp (may be 0 to indicate now)
346 */
347 void AppendInteger(int entry, int64_t value, int64_t timestamp);
348
349 /**
350 * Appends a float record to the log.
351 *
352 * @param entry Entry index, as returned by Start()
353 * @param value Float value to record
354 * @param timestamp Time stamp (may be 0 to indicate now)
355 */
356 void AppendFloat(int entry, float value, int64_t timestamp);
357
358 /**
359 * Appends a double record to the log.
360 *
361 * @param entry Entry index, as returned by Start()
362 * @param value Double value to record
363 * @param timestamp Time stamp (may be 0 to indicate now)
364 */
365 void AppendDouble(int entry, double value, int64_t timestamp);
366
367 /**
368 * Appends a string record to the log.
369 *
370 * @param entry Entry index, as returned by Start()
371 * @param value String value to record
372 * @param timestamp Time stamp (may be 0 to indicate now)
373 */
374 void AppendString(int entry, std::string_view value, int64_t timestamp);
375
376 /**
377 * Appends a boolean array record to the log.
378 *
379 * @param entry Entry index, as returned by Start()
380 * @param arr Boolean array to record
381 * @param timestamp Time stamp (may be 0 to indicate now)
382 */
383 void AppendBooleanArray(int entry, std::span<const bool> arr,
384 int64_t timestamp);
385
386 /**
387 * Appends a boolean array record to the log.
388 *
389 * @param entry Entry index, as returned by Start()
390 * @param arr Boolean array to record
391 * @param timestamp Time stamp (may be 0 to indicate now)
392 */
393 void AppendBooleanArray(int entry, std::span<const int> arr,
394 int64_t timestamp);
395
396 /**
397 * Appends a boolean array record to the log.
398 *
399 * @param entry Entry index, as returned by Start()
400 * @param arr Boolean array to record
401 * @param timestamp Time stamp (may be 0 to indicate now)
402 */
403 void AppendBooleanArray(int entry, std::span<const uint8_t> arr,
404 int64_t timestamp);
405
406 /**
407 * Appends an integer array record to the log.
408 *
409 * @param entry Entry index, as returned by Start()
410 * @param arr Integer array to record
411 * @param timestamp Time stamp (may be 0 to indicate now)
412 */
413 void AppendIntegerArray(int entry, std::span<const int64_t> arr,
414 int64_t timestamp);
415
416 /**
417 * Appends a float array record to the log.
418 *
419 * @param entry Entry index, as returned by Start()
420 * @param arr Float array to record
421 * @param timestamp Time stamp (may be 0 to indicate now)
422 */
423 void AppendFloatArray(int entry, std::span<const float> arr,
424 int64_t timestamp);
425
426 /**
427 * Appends a double array record to the log.
428 *
429 * @param entry Entry index, as returned by Start()
430 * @param arr Double array to record
431 * @param timestamp Time stamp (may be 0 to indicate now)
432 */
433 void AppendDoubleArray(int entry, std::span<const double> arr,
434 int64_t timestamp);
435
436 /**
437 * Appends a string array record to the log.
438 *
439 * @param entry Entry index, as returned by Start()
440 * @param arr String array to record
441 * @param timestamp Time stamp (may be 0 to indicate now)
442 */
443 void AppendStringArray(int entry, std::span<const std::string> arr,
444 int64_t timestamp);
445
446 /**
447 * Appends a string array record to the log.
448 *
449 * @param entry Entry index, as returned by Start()
450 * @param arr String array to record
451 * @param timestamp Time stamp (may be 0 to indicate now)
452 */
453 void AppendStringArray(int entry, std::span<const std::string_view> arr,
454 int64_t timestamp);
455
456 /**
457 * Appends a string array record to the log.
458 *
459 * @param entry Entry index, as returned by Start()
460 * @param arr String array to record
461 * @param timestamp Time stamp (may be 0 to indicate now)
462 */
463 void AppendStringArray(int entry, std::span<const WPI_DataLog_String> arr,
464 int64_t timestamp);
465
466 private:
467 struct WriterThreadState;
468
469 void StartLogFile(WriterThreadState& state);
470 void WriterThreadMain(std::string_view dir);
471 void WriterThreadMain(
472 std::function<void(std::span<const uint8_t> data)> write);
473
474 // must be called with m_mutex held
476 std::string_view metadata, int64_t timestamp);
477 uint8_t* StartRecord(uint32_t entry, uint64_t timestamp, uint32_t payloadSize,
478 size_t reserveSize);
479 uint8_t* Reserve(size_t size);
480 void AppendImpl(std::span<const uint8_t> data);
481 void AppendStringImpl(std::string_view str);
482 void AppendStartRecord(int id, std::string_view name, std::string_view type,
483 std::string_view metadata, int64_t timestamp);
484
485 wpi::Logger& m_msglog;
486 mutable wpi::mutex m_mutex;
488 bool m_doFlush{false};
489 enum State {
490 kStart,
491 kActive,
492 kPaused,
493 kStopped,
494 kShutdown,
495 } m_state = kActive;
496 double m_period;
497 std::string m_extraHeader;
498 std::string m_newFilename;
499 class Buffer;
500 std::vector<Buffer> m_free;
501 std::vector<Buffer> m_outgoing;
502 struct EntryInfo {
503 std::string type;
504 std::vector<uint8_t> schemaData; // only set for schema entries
505 int id{0};
506 };
508 struct EntryInfo2 {
509 std::string metadata;
510 unsigned int count;
511 };
513 int m_lastId = 0;
514 std::thread m_thread;
515};
516
517/**
518 * Log entry base class.
519 */
521 protected:
522 DataLogEntry() = default;
524 std::string_view metadata = {}, int64_t timestamp = 0)
525 : m_log{&log}, m_entry{log.Start(name, type, metadata, timestamp)} {}
526
527 public:
528 DataLogEntry(const DataLogEntry&) = delete;
530
532 rhs.m_log = nullptr;
533 }
535 if (m_log) {
537 }
538 m_log = rhs.m_log;
539 rhs.m_log = nullptr;
540 m_entry = rhs.m_entry;
541 return *this;
542 }
543
544 explicit operator bool() const { return m_log != nullptr; }
545
546 /**
547 * Updates the metadata for the entry.
548 *
549 * @param metadata New metadata for the entry
550 * @param timestamp Time stamp (may be 0 to indicate now)
551 */
552 void SetMetadata(std::string_view metadata, int64_t timestamp = 0) {
553 m_log->SetMetadata(m_entry, metadata, timestamp);
554 }
555
556 /**
557 * Finishes the entry.
558 *
559 * @param timestamp Time stamp (may be 0 to indicate now)
560 */
561 void Finish(int64_t timestamp = 0) { m_log->Finish(m_entry, timestamp); }
562
563 protected:
564 DataLog* m_log = nullptr;
565 int m_entry = 0;
566};
567
568/**
569 * Log arbitrary byte data.
570 */
571class RawLogEntry : public DataLogEntry {
572 public:
573 static constexpr std::string_view kDataType = "raw";
574
575 RawLogEntry() = default;
576 RawLogEntry(DataLog& log, std::string_view name, int64_t timestamp = 0)
577 : RawLogEntry{log, name, {}, kDataType, timestamp} {}
579 int64_t timestamp = 0)
580 : RawLogEntry{log, name, metadata, kDataType, timestamp} {}
582 std::string_view type, int64_t timestamp = 0)
583 : DataLogEntry{log, name, type, metadata, timestamp} {}
584
585 /**
586 * Appends a record to the log.
587 *
588 * @param data Data to record
589 * @param timestamp Time stamp (may be 0 to indicate now)
590 */
591 void Append(std::span<const uint8_t> data, int64_t timestamp = 0) {
592 m_log->AppendRaw(m_entry, data, timestamp);
593 }
594};
595
596/**
597 * Log boolean values.
598 */
600 public:
601 static constexpr std::string_view kDataType = "boolean";
602
603 BooleanLogEntry() = default;
605 : BooleanLogEntry{log, name, {}, timestamp} {}
607 std::string_view metadata, int64_t timestamp = 0)
608 : DataLogEntry{log, name, kDataType, metadata, timestamp} {}
609
610 /**
611 * Appends a record to the log.
612 *
613 * @param value Value to record
614 * @param timestamp Time stamp (may be 0 to indicate now)
615 */
616 void Append(bool value, int64_t timestamp = 0) {
617 m_log->AppendBoolean(m_entry, value, timestamp);
618 }
619};
620
621/**
622 * Log integer values.
623 */
625 public:
626 static constexpr std::string_view kDataType = "int64";
627
628 IntegerLogEntry() = default;
630 : IntegerLogEntry{log, name, {}, timestamp} {}
632 std::string_view metadata, int64_t timestamp = 0)
633 : DataLogEntry{log, name, kDataType, metadata, timestamp} {}
634
635 /**
636 * Appends a record to the log.
637 *
638 * @param value Value to record
639 * @param timestamp Time stamp (may be 0 to indicate now)
640 */
641 void Append(int64_t value, int64_t timestamp = 0) {
642 m_log->AppendInteger(m_entry, value, timestamp);
643 }
644};
645
646/**
647 * Log float values.
648 */
650 public:
651 static constexpr std::string_view kDataType = "float";
652
653 FloatLogEntry() = default;
655 : FloatLogEntry{log, name, {}, timestamp} {}
657 int64_t timestamp = 0)
658 : DataLogEntry{log, name, kDataType, metadata, timestamp} {}
659
660 /**
661 * Appends a record to the log.
662 *
663 * @param value Value to record
664 * @param timestamp Time stamp (may be 0 to indicate now)
665 */
666 void Append(float value, int64_t timestamp = 0) {
667 m_log->AppendFloat(m_entry, value, timestamp);
668 }
669};
670
671/**
672 * Log double values.
673 */
675 public:
676 static constexpr std::string_view kDataType = "double";
677
678 DoubleLogEntry() = default;
680 : DoubleLogEntry{log, name, {}, timestamp} {}
682 int64_t timestamp = 0)
683 : DataLogEntry{log, name, kDataType, metadata, timestamp} {}
684
685 /**
686 * Appends a record to the log.
687 *
688 * @param value Value to record
689 * @param timestamp Time stamp (may be 0 to indicate now)
690 */
691 void Append(double value, int64_t timestamp = 0) {
692 m_log->AppendDouble(m_entry, value, timestamp);
693 }
694};
695
696/**
697 * Log string values.
698 */
700 public:
701 static constexpr const char* kDataType = "string";
702
703 StringLogEntry() = default;
705 : StringLogEntry{log, name, {}, kDataType, timestamp} {}
707 int64_t timestamp = 0)
708 : StringLogEntry{log, name, metadata, kDataType, timestamp} {}
710 std::string_view type, int64_t timestamp = 0)
711 : DataLogEntry{log, name, type, metadata, timestamp} {}
712
713 /**
714 * Appends a record to the log.
715 *
716 * @param value Value to record
717 * @param timestamp Time stamp (may be 0 to indicate now)
718 */
719 void Append(std::string_view value, int64_t timestamp = 0) {
720 m_log->AppendString(m_entry, value, timestamp);
721 }
722};
723
724/**
725 * Log array of boolean values.
726 */
728 public:
729 static constexpr const char* kDataType = "boolean[]";
730
733 int64_t timestamp = 0)
734 : BooleanArrayLogEntry{log, name, {}, timestamp} {}
736 std::string_view metadata, int64_t timestamp = 0)
737 : DataLogEntry{log, name, kDataType, metadata, timestamp} {}
738
739 /**
740 * Appends a record to the log. For find functions to work, timestamp
741 * must be monotonically increasing.
742 *
743 * @param arr Values to record
744 * @param timestamp Time stamp (may be 0 to indicate now)
745 */
746 void Append(std::span<const bool> arr, int64_t timestamp = 0) {
747 m_log->AppendBooleanArray(m_entry, arr, timestamp);
748 }
749
750 /**
751 * Appends a record to the log.
752 *
753 * @param arr Values to record
754 * @param timestamp Time stamp (may be 0 to indicate now)
755 */
756 void Append(std::initializer_list<bool> arr, int64_t timestamp = 0) {
757 Append(std::span{arr.begin(), arr.end()}, timestamp);
758 }
759
760 /**
761 * Appends a record to the log.
762 *
763 * @param arr Values to record
764 * @param timestamp Time stamp (may be 0 to indicate now)
765 */
766 void Append(std::span<const int> arr, int64_t timestamp = 0) {
767 m_log->AppendBooleanArray(m_entry, arr, timestamp);
768 }
769
770 /**
771 * Appends a record to the log.
772 *
773 * @param arr Values to record
774 * @param timestamp Time stamp (may be 0 to indicate now)
775 */
776 void Append(std::initializer_list<int> arr, int64_t timestamp = 0) {
777 Append(std::span{arr.begin(), arr.end()}, timestamp);
778 }
779
780 /**
781 * Appends a record to the log.
782 *
783 * @param arr Values to record
784 * @param timestamp Time stamp (may be 0 to indicate now)
785 */
786 void Append(std::span<const uint8_t> arr, int64_t timestamp = 0) {
787 m_log->AppendBooleanArray(m_entry, arr, timestamp);
788 }
789};
790
791/**
792 * Log array of integer values.
793 */
795 public:
796 static constexpr const char* kDataType = "int64[]";
797
800 int64_t timestamp = 0)
801 : IntegerArrayLogEntry{log, name, {}, timestamp} {}
803 std::string_view metadata, int64_t timestamp = 0)
804 : DataLogEntry{log, name, kDataType, metadata, timestamp} {}
805
806 /**
807 * Appends a record to the log.
808 *
809 * @param arr Values to record
810 * @param timestamp Time stamp (may be 0 to indicate now)
811 */
812 void Append(std::span<const int64_t> arr, int64_t timestamp = 0) {
813 m_log->AppendIntegerArray(m_entry, arr, timestamp);
814 }
815
816 /**
817 * Appends a record to the log.
818 *
819 * @param arr Values to record
820 * @param timestamp Time stamp (may be 0 to indicate now)
821 */
822 void Append(std::initializer_list<int64_t> arr, int64_t timestamp = 0) {
823 Append({arr.begin(), arr.end()}, timestamp);
824 }
825};
826
827/**
828 * Log array of float values.
829 */
831 public:
832 static constexpr const char* kDataType = "float[]";
833
836 : FloatArrayLogEntry{log, name, {}, timestamp} {}
838 std::string_view metadata, int64_t timestamp = 0)
839 : DataLogEntry{log, name, kDataType, metadata, timestamp} {}
840
841 /**
842 * Appends a record to the log.
843 *
844 * @param arr Values to record
845 * @param timestamp Time stamp (may be 0 to indicate now)
846 */
847 void Append(std::span<const float> arr, int64_t timestamp = 0) {
848 m_log->AppendFloatArray(m_entry, arr, timestamp);
849 }
850
851 /**
852 * Appends a record to the log.
853 *
854 * @param arr Values to record
855 * @param timestamp Time stamp (may be 0 to indicate now)
856 */
857 void Append(std::initializer_list<float> arr, int64_t timestamp = 0) {
858 Append({arr.begin(), arr.end()}, timestamp);
859 }
860};
861
862/**
863 * Log array of double values.
864 */
866 public:
867 static constexpr const char* kDataType = "double[]";
868
871 int64_t timestamp = 0)
872 : DoubleArrayLogEntry{log, name, {}, timestamp} {}
874 std::string_view metadata, int64_t timestamp = 0)
875 : DataLogEntry{log, name, kDataType, metadata, timestamp} {}
876
877 /**
878 * Appends a record to the log.
879 *
880 * @param arr Values to record
881 * @param timestamp Time stamp (may be 0 to indicate now)
882 */
883 void Append(std::span<const double> arr, int64_t timestamp = 0) {
884 m_log->AppendDoubleArray(m_entry, arr, timestamp);
885 }
886
887 /**
888 * Appends a record to the log.
889 *
890 * @param arr Values to record
891 * @param timestamp Time stamp (may be 0 to indicate now)
892 */
893 void Append(std::initializer_list<double> arr, int64_t timestamp = 0) {
894 Append({arr.begin(), arr.end()}, timestamp);
895 }
896};
897
898/**
899 * Log array of string values.
900 */
902 public:
903 static constexpr const char* kDataType = "string[]";
904
907 int64_t timestamp = 0)
908 : StringArrayLogEntry{log, name, {}, timestamp} {}
910 std::string_view metadata, int64_t timestamp = 0)
911 : DataLogEntry{log, name, kDataType, metadata, timestamp} {}
912
913 /**
914 * Appends a record to the log.
915 *
916 * @param arr Values to record
917 * @param timestamp Time stamp (may be 0 to indicate now)
918 */
919 void Append(std::span<const std::string> arr, int64_t timestamp = 0) {
920 m_log->AppendStringArray(m_entry, arr, timestamp);
921 }
922
923 /**
924 * Appends a record to the log.
925 *
926 * @param arr Values to record
927 * @param timestamp Time stamp (may be 0 to indicate now)
928 */
929 void Append(std::span<const std::string_view> arr, int64_t timestamp = 0) {
930 m_log->AppendStringArray(m_entry, arr, timestamp);
931 }
932
933 /**
934 * Appends a record to the log.
935 *
936 * @param arr Values to record
937 * @param timestamp Time stamp (may be 0 to indicate now)
938 */
939 void Append(std::initializer_list<std::string_view> arr,
940 int64_t timestamp = 0) {
941 Append(std::span<const std::string_view>{arr.begin(), arr.end()},
942 timestamp);
943 }
944};
945
946/**
947 * Log raw struct serializable objects.
948 */
949template <StructSerializable T>
951 using S = Struct<T>;
952
953 public:
954 StructLogEntry() = default;
956 : StructLogEntry{log, name, {}, timestamp} {}
958 int64_t timestamp = 0) {
959 m_log = &log;
960 log.AddStructSchema<T>(timestamp);
961 m_entry = log.Start(name, S::kTypeString, metadata, timestamp);
962 }
963
964 /**
965 * Appends a record to the log.
966 *
967 * @param data Data to record
968 * @param timestamp Time stamp (may be 0 to indicate now)
969 */
970 void Append(const T& data, int64_t timestamp = 0) {
971 if constexpr (wpi::is_constexpr([] { S::GetSize(); })) {
972 uint8_t buf[S::GetSize()];
973 S::Pack(buf, data);
974 m_log->AppendRaw(m_entry, buf, timestamp);
975 } else {
977 buf.resize_for_overwrite(S::GetSize());
978 S::Pack(buf, data);
979 m_log->AppendRaw(m_entry, buf, timestamp);
980 }
981 }
982};
983
984/**
985 * Log raw struct serializable array of objects.
986 */
987template <StructSerializable T>
989 using S = Struct<T>;
990
991 public:
994 int64_t timestamp = 0)
995 : StructArrayLogEntry{log, name, {}, timestamp} {}
997 std::string_view metadata, int64_t timestamp = 0) {
998 m_log = &log;
999 log.AddStructSchema<T>(timestamp);
1000 m_entry =
1001 log.Start(name, MakeStructArrayTypeString<T, std::dynamic_extent>(),
1002 metadata, timestamp);
1003 }
1004
1005 /**
1006 * Appends a record to the log.
1007 *
1008 * @param data Data to record
1009 * @param timestamp Time stamp (may be 0 to indicate now)
1010 */
1011 template <typename U>
1012#if __cpp_lib_ranges >= 201911L
1013 requires std::ranges::range<U> &&
1014 std::convertible_to<std::ranges::range_value_t<U>, T>
1015#endif
1016 void Append(U&& data, int64_t timestamp = 0) {
1017 m_buf.Write(std::forward<U>(data), [&](auto bytes) {
1018 m_log->AppendRaw(m_entry, bytes, timestamp);
1019 });
1020 }
1021
1022 /**
1023 * Appends a record to the log.
1024 *
1025 * @param data Data to record
1026 * @param timestamp Time stamp (may be 0 to indicate now)
1027 */
1028 void Append(std::span<const T> data, int64_t timestamp = 0) {
1029 m_buf.Write(
1030 data, [&](auto bytes) { m_log->AppendRaw(m_entry, bytes, timestamp); });
1031 }
1032
1033 private:
1035};
1036
1037/**
1038 * Log protobuf serializable objects.
1039 */
1040template <ProtobufSerializable T>
1042 using P = Protobuf<T>;
1043
1044 public:
1045 ProtobufLogEntry() = default;
1047 : ProtobufLogEntry{log, name, {}, timestamp} {}
1049 std::string_view metadata, int64_t timestamp = 0) {
1050 m_log = &log;
1051 log.AddProtobufSchema<T>(m_msg, timestamp);
1052 m_entry = log.Start(name, m_msg.GetTypeString(), metadata, timestamp);
1053 }
1054
1055 /**
1056 * Appends a record to the log.
1057 *
1058 * @param data Data to record
1059 * @param timestamp Time stamp (may be 0 to indicate now)
1060 */
1061 void Append(const T& data, int64_t timestamp = 0) {
1063 {
1064 std::scoped_lock lock{m_mutex};
1065 m_msg.Pack(buf, data);
1066 }
1067 m_log->AppendRaw(m_entry, buf, timestamp);
1068 }
1069
1070 private:
1071 wpi::mutex m_mutex;
1072 ProtobufMessage<T> m_msg;
1073};
1074
1075} // namespace wpi::log
1076
1077extern "C" {
1078#endif // __cplusplus
1079
1080/** C-compatible data log (opaque struct). */
1081struct WPI_DataLog;
1082
1083/**
1084 * Construct a new Data Log. The log will be initially created with a
1085 * temporary filename.
1086 *
1087 * @param dir directory to store the log
1088 * @param filename filename to use; if none provided, a random filename is
1089 * generated of the form "wpilog_{}.wpilog"
1090 * @param period time between automatic flushes to disk, in seconds;
1091 * this is a time/storage tradeoff
1092 * @param extraHeader extra header data
1093 */
1094struct WPI_DataLog* WPI_DataLog_Create(const char* dir, const char* filename,
1095 double period, const char* extraHeader);
1096
1097/**
1098 * Construct a new Data Log that passes its output to the provided function
1099 * rather than a file. The write function will be called on a separate
1100 * background thread and may block. The write function is called with an
1101 * empty data array (data=NULL, len=0) when the thread is terminating.
1102 *
1103 * @param write write function
1104 * @param ptr pointer to pass to write function ptr parameter
1105 * @param period time between automatic calls to write, in seconds;
1106 * this is a time/storage tradeoff
1107 * @param extraHeader extra header data
1108 */
1109struct WPI_DataLog* WPI_DataLog_Create_Func(
1110 void (*write)(void* ptr, const uint8_t* data, size_t len), void* ptr,
1111 double period, const char* extraHeader);
1112
1113/**
1114 * Releases a data log object. Closes the file and returns resources to the
1115 * system.
1116 *
1117 * @param datalog data log
1118 */
1119void WPI_DataLog_Release(struct WPI_DataLog* datalog);
1120
1121/**
1122 * Change log filename.
1123 *
1124 * @param datalog data log
1125 * @param filename filename
1126 */
1127void WPI_DataLog_SetFilename(struct WPI_DataLog* datalog, const char* filename);
1128
1129/**
1130 * Explicitly flushes the log data to disk.
1131 *
1132 * @param datalog data log
1133 */
1134void WPI_DataLog_Flush(struct WPI_DataLog* datalog);
1135
1136/**
1137 * Pauses appending of data records to the log. While paused, no data records
1138 * are saved (e.g. AppendX is a no-op). Has no effect on entry starts /
1139 * finishes / metadata changes.
1140 *
1141 * @param datalog data log
1142 */
1143void WPI_DataLog_Pause(struct WPI_DataLog* datalog);
1144
1145/**
1146 * Resumes appending of data records to the log. If called after Stop(),
1147 * opens a new file (with random name if SetFilename was not called after
1148 * Stop()) and appends Start records and schema data values for all previously
1149 * started entries and schemas.
1150 *
1151 * @param datalog data log
1152 */
1153void WPI_DataLog_Resume(struct WPI_DataLog* datalog);
1154
1155/**
1156 * Stops appending all records to the log, and closes the log file.
1157 *
1158 * @param datalog data log
1159 */
1160void WPI_DataLog_Stop(struct WPI_DataLog* datalog);
1161
1162/**
1163 * Start an entry. Duplicate names are allowed (with the same type), and
1164 * result in the same index being returned (Start/Finish are reference
1165 * counted). A duplicate name with a different type will result in an error
1166 * message being printed to the console and 0 being returned (which will be
1167 * ignored by the Append functions).
1168 *
1169 * @param datalog data log
1170 * @param name Name
1171 * @param type Data type
1172 * @param metadata Initial metadata (e.g. data properties)
1173 * @param timestamp Time stamp (may be 0 to indicate now)
1174 *
1175 * @return Entry index
1176 */
1177int WPI_DataLog_Start(struct WPI_DataLog* datalog, const char* name,
1178 const char* type, const char* metadata,
1179 int64_t timestamp);
1180
1181/**
1182 * Finish an entry.
1183 *
1184 * @param datalog data log
1185 * @param entry Entry index
1186 * @param timestamp Time stamp (may be 0 to indicate now)
1187 */
1188void WPI_DataLog_Finish(struct WPI_DataLog* datalog, int entry,
1189 int64_t timestamp);
1190
1191/**
1192 * Updates the metadata for an entry.
1193 *
1194 * @param datalog data log
1195 * @param entry Entry index
1196 * @param metadata New metadata for the entry
1197 * @param timestamp Time stamp (may be 0 to indicate now)
1198 */
1199void WPI_DataLog_SetMetadata(struct WPI_DataLog* datalog, int entry,
1200 const char* metadata, int64_t timestamp);
1201
1202/**
1203 * Appends a raw record to the log.
1204 *
1205 * @param datalog data log
1206 * @param entry Entry index, as returned by WPI_DataLog_Start()
1207 * @param data Byte array to record
1208 * @param len Length of byte array
1209 * @param timestamp Time stamp (may be 0 to indicate now)
1210 */
1211void WPI_DataLog_AppendRaw(struct WPI_DataLog* datalog, int entry,
1212 const uint8_t* data, size_t len, int64_t timestamp);
1213
1214/**
1215 * Appends a boolean record to the log.
1216 *
1217 * @param datalog data log
1218 * @param entry Entry index, as returned by WPI_DataLog_Start()
1219 * @param value Boolean value to record
1220 * @param timestamp Time stamp (may be 0 to indicate now)
1221 */
1222void WPI_DataLog_AppendBoolean(struct WPI_DataLog* datalog, int entry,
1223 int value, int64_t timestamp);
1224
1225/**
1226 * Appends an integer record to the log.
1227 *
1228 * @param datalog data log
1229 * @param entry Entry index, as returned by WPI_DataLog_Start()
1230 * @param value Integer value to record
1231 * @param timestamp Time stamp (may be 0 to indicate now)
1232 */
1233void WPI_DataLog_AppendInteger(struct WPI_DataLog* datalog, int entry,
1234 int64_t value, int64_t timestamp);
1235
1236/**
1237 * Appends a float record to the log.
1238 *
1239 * @param datalog data log
1240 * @param entry Entry index, as returned by WPI_DataLog_Start()
1241 * @param value Float value to record
1242 * @param timestamp Time stamp (may be 0 to indicate now)
1243 */
1244void WPI_DataLog_AppendFloat(struct WPI_DataLog* datalog, int entry,
1245 float value, int64_t timestamp);
1246
1247/**
1248 * Appends a double record to the log.
1249 *
1250 * @param datalog data log
1251 * @param entry Entry index, as returned by WPI_DataLog_Start()
1252 * @param value Double value to record
1253 * @param timestamp Time stamp (may be 0 to indicate now)
1254 */
1255void WPI_DataLog_AppendDouble(struct WPI_DataLog* datalog, int entry,
1256 double value, int64_t timestamp);
1257
1258/**
1259 * Appends a string record to the log.
1260 *
1261 * @param datalog data log
1262 * @param entry Entry index, as returned by WPI_DataLog_Start()
1263 * @param value String value to record
1264 * @param len Length of string
1265 * @param timestamp Time stamp (may be 0 to indicate now)
1266 */
1267void WPI_DataLog_AppendString(struct WPI_DataLog* datalog, int entry,
1268 const char* value, size_t len, int64_t timestamp);
1269
1270/**
1271 * Appends a boolean array record to the log.
1272 *
1273 * @param datalog data log
1274 * @param entry Entry index, as returned by WPI_DataLog_Start()
1275 * @param arr Boolean array to record
1276 * @param len Number of elements in array
1277 * @param timestamp Time stamp (may be 0 to indicate now)
1278 */
1279void WPI_DataLog_AppendBooleanArray(struct WPI_DataLog* datalog, int entry,
1280 const int* arr, size_t len,
1281 int64_t timestamp);
1282
1283/**
1284 * Appends a boolean array record to the log.
1285 *
1286 * @param datalog data log
1287 * @param entry Entry index, as returned by WPI_DataLog_Start()
1288 * @param arr Boolean array to record
1289 * @param len Number of elements in array
1290 * @param timestamp Time stamp (may be 0 to indicate now)
1291 */
1292void WPI_DataLog_AppendBooleanArrayByte(struct WPI_DataLog* datalog, int entry,
1293 const uint8_t* arr, size_t len,
1294 int64_t timestamp);
1295
1296/**
1297 * Appends an integer array record to the log.
1298 *
1299 * @param datalog data log
1300 * @param entry Entry index, as returned by WPI_DataLog_Start()
1301 * @param arr Integer array to record
1302 * @param len Number of elements in array
1303 * @param timestamp Time stamp (may be 0 to indicate now)
1304 */
1305void WPI_DataLog_AppendIntegerArray(struct WPI_DataLog* datalog, int entry,
1306 const int64_t* arr, size_t len,
1307 int64_t timestamp);
1308
1309/**
1310 * Appends a float array record to the log.
1311 *
1312 * @param datalog data log
1313 * @param entry Entry index, as returned by WPI_DataLog_Start()
1314 * @param arr Float array to record
1315 * @param len Number of elements in array
1316 * @param timestamp Time stamp (may be 0 to indicate now)
1317 */
1318void WPI_DataLog_AppendFloatArray(struct WPI_DataLog* datalog, int entry,
1319 const float* arr, size_t len,
1320 int64_t timestamp);
1321
1322/**
1323 * Appends a double array record to the log.
1324 *
1325 * @param datalog data log
1326 * @param entry Entry index, as returned by WPI_DataLog_Start()
1327 * @param arr Double array to record
1328 * @param len Number of elements in array
1329 * @param timestamp Time stamp (may be 0 to indicate now)
1330 */
1331void WPI_DataLog_AppendDoubleArray(struct WPI_DataLog* datalog, int entry,
1332 const double* arr, size_t len,
1333 int64_t timestamp);
1334
1335/**
1336 * Appends a string array record to the log.
1337 *
1338 * @param datalog data log
1339 * @param entry Entry index, as returned by WPI_DataLog_Start()
1340 * @param arr String array to record
1341 * @param len Number of elements in array
1342 * @param timestamp Time stamp (may be 0 to indicate now)
1343 */
1344void WPI_DataLog_AppendStringArray(struct WPI_DataLog* datalog, int entry,
1345 const WPI_DataLog_String* arr, size_t len,
1346 int64_t timestamp);
1347
1348#ifdef __cplusplus
1349} // extern "C"
1350#endif // __cplusplus
void WPI_DataLog_AppendInteger(struct WPI_DataLog *datalog, int entry, int64_t value, int64_t timestamp)
Appends an integer record to the log.
void WPI_DataLog_SetMetadata(struct WPI_DataLog *datalog, int entry, const char *metadata, int64_t timestamp)
Updates the metadata for an entry.
void WPI_DataLog_AppendBoolean(struct WPI_DataLog *datalog, int entry, int value, int64_t timestamp)
Appends a boolean record to the log.
void WPI_DataLog_AppendDoubleArray(struct WPI_DataLog *datalog, int entry, const double *arr, size_t len, int64_t timestamp)
Appends a double array record to the log.
void WPI_DataLog_Stop(struct WPI_DataLog *datalog)
Stops appending all records to the log, and closes the log file.
struct WPI_DataLog * WPI_DataLog_Create(const char *dir, const char *filename, double period, const char *extraHeader)
Construct a new Data Log.
void WPI_DataLog_AppendRaw(struct WPI_DataLog *datalog, int entry, const uint8_t *data, size_t len, int64_t timestamp)
Appends a raw record to the log.
void WPI_DataLog_Resume(struct WPI_DataLog *datalog)
Resumes appending of data records to the log.
struct WPI_DataLog * WPI_DataLog_Create_Func(void(*write)(void *ptr, const uint8_t *data, size_t len), void *ptr, double period, const char *extraHeader)
Construct a new Data Log that passes its output to the provided function rather than a file.
void WPI_DataLog_AppendBooleanArrayByte(struct WPI_DataLog *datalog, int entry, const uint8_t *arr, size_t len, int64_t timestamp)
Appends a boolean array record to the log.
void WPI_DataLog_SetFilename(struct WPI_DataLog *datalog, const char *filename)
Change log filename.
void WPI_DataLog_Pause(struct WPI_DataLog *datalog)
Pauses appending of data records to the log.
void WPI_DataLog_AppendString(struct WPI_DataLog *datalog, int entry, const char *value, size_t len, int64_t timestamp)
Appends a string record to the log.
void WPI_DataLog_Finish(struct WPI_DataLog *datalog, int entry, int64_t timestamp)
Finish an entry.
void WPI_DataLog_AppendDouble(struct WPI_DataLog *datalog, int entry, double value, int64_t timestamp)
Appends a double record to the log.
void WPI_DataLog_Release(struct WPI_DataLog *datalog)
Releases a data log object.
void WPI_DataLog_AppendBooleanArray(struct WPI_DataLog *datalog, int entry, const int *arr, size_t len, int64_t timestamp)
Appends a boolean array record to the log.
void WPI_DataLog_Flush(struct WPI_DataLog *datalog)
Explicitly flushes the log data to disk.
void WPI_DataLog_AppendStringArray(struct WPI_DataLog *datalog, int entry, const WPI_DataLog_String *arr, size_t len, int64_t timestamp)
Appends a string array record to the log.
void WPI_DataLog_AppendFloatArray(struct WPI_DataLog *datalog, int entry, const float *arr, size_t len, int64_t timestamp)
Appends a float array record to the log.
void WPI_DataLog_AppendIntegerArray(struct WPI_DataLog *datalog, int entry, const int64_t *arr, size_t len, int64_t timestamp)
Appends an integer array record to the log.
void WPI_DataLog_AppendFloat(struct WPI_DataLog *datalog, int entry, float value, int64_t timestamp)
Appends a float record to the log.
int WPI_DataLog_Start(struct WPI_DataLog *datalog, const char *name, const char *type, const char *metadata, int64_t timestamp)
Start an entry.
This file defines the DenseMap class.
This file defines the SmallVector class.
This file defines the StringMap class.
Definition: format.h:4134
Definition: Logger.h:27
Owning wrapper (ala std::unique_ptr) for google::protobuf::Message* that does not require the protobu...
Definition: Protobuf.h:158
void ForEachProtobufDescriptor(function_ref< bool(std::string_view filename)> exists, function_ref< void(std::string_view filename, std::span< const uint8_t > descriptor)> fn)
Loops over all protobuf descriptors including nested/referenced descriptors.
Definition: Protobuf.h:248
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1202
void resize_for_overwrite(size_type N)
Like resize, but T is POD, the new values won't be initialized.
Definition: SmallVector.h:647
Definition: Struct.h:289
Log array of boolean values.
Definition: DataLog.h:727
void Append(std::span< const uint8_t > arr, int64_t timestamp=0)
Appends a record to the log.
Definition: DataLog.h:786
void Append(std::initializer_list< bool > arr, int64_t timestamp=0)
Appends a record to the log.
Definition: DataLog.h:756
BooleanArrayLogEntry(DataLog &log, std::string_view name, int64_t timestamp=0)
Definition: DataLog.h:732
void Append(std::initializer_list< int > arr, int64_t timestamp=0)
Appends a record to the log.
Definition: DataLog.h:776
void Append(std::span< const int > arr, int64_t timestamp=0)
Appends a record to the log.
Definition: DataLog.h:766
void Append(std::span< const bool > arr, int64_t timestamp=0)
Appends a record to the log.
Definition: DataLog.h:746
BooleanArrayLogEntry(DataLog &log, std::string_view name, std::string_view metadata, int64_t timestamp=0)
Definition: DataLog.h:735
BooleanArrayLogEntry()=default
Log boolean values.
Definition: DataLog.h:599
BooleanLogEntry()=default
BooleanLogEntry(DataLog &log, std::string_view name, std::string_view metadata, int64_t timestamp=0)
Definition: DataLog.h:606
void Append(bool value, int64_t timestamp=0)
Appends a record to the log.
Definition: DataLog.h:616
BooleanLogEntry(DataLog &log, std::string_view name, int64_t timestamp=0)
Definition: DataLog.h:604
Log entry base class.
Definition: DataLog.h:520
DataLogEntry(DataLogEntry &&rhs)
Definition: DataLog.h:531
DataLogEntry(const DataLogEntry &)=delete
void Finish(int64_t timestamp=0)
Finishes the entry.
Definition: DataLog.h:561
DataLog * m_log
Definition: DataLog.h:564
DataLogEntry(DataLog &log, std::string_view name, std::string_view type, std::string_view metadata={}, int64_t timestamp=0)
Definition: DataLog.h:523
DataLogEntry()=default
DataLogEntry & operator=(const DataLogEntry &)=delete
int m_entry
Definition: DataLog.h:565
DataLogEntry & operator=(DataLogEntry &&rhs)
Definition: DataLog.h:534
void SetMetadata(std::string_view metadata, int64_t timestamp=0)
Updates the metadata for the entry.
Definition: DataLog.h:552
A data log.
Definition: DataLog.h:89
void AppendBooleanArray(int entry, std::span< const bool > arr, int64_t timestamp)
Appends a boolean array record to the log.
void Stop()
Stops appending all records to the log, and closes the log file.
void AppendBooleanArray(int entry, std::span< const int > arr, int64_t timestamp)
Appends a boolean array record to the log.
void SetMetadata(int entry, std::string_view metadata, int64_t timestamp=0)
Updates the metadata for an entry.
void AppendStringArray(int entry, std::span< const std::string > arr, int64_t timestamp)
Appends a string array record to the log.
int Start(std::string_view name, std::string_view type, std::string_view metadata={}, int64_t timestamp=0)
Start an entry.
DataLog & operator=(const DataLog &)=delete
DataLog(std::string_view dir="", std::string_view filename="", double period=0.25, std::string_view extraHeader="")
Construct a new Data Log.
void Flush()
Explicitly flushes the log data to disk.
void AppendRaw(int entry, std::span< const uint8_t > data, int64_t timestamp)
Appends a raw record to the log.
void AppendIntegerArray(int entry, std::span< const int64_t > arr, int64_t timestamp)
Appends an integer array record to the log.
DataLog(const DataLog &)=delete
void AddSchema(std::string_view name, std::string_view type, std::string_view schema, int64_t timestamp=0)
Registers a data schema.
Definition: DataLog.h:232
void AppendBooleanArray(int entry, std::span< const uint8_t > arr, int64_t timestamp)
Appends a boolean array record to the log.
void AppendDouble(int entry, double value, int64_t timestamp)
Appends a double record to the log.
void AppendFloat(int entry, float value, int64_t timestamp)
Appends a float record to the log.
DataLog & operator=(const DataLog &&)=delete
void AppendFloatArray(int entry, std::span< const float > arr, int64_t timestamp)
Appends a float array record to the log.
DataLog(std::function< void(std::span< const uint8_t > data)> write, double period=0.25, std::string_view extraHeader="")
Construct a new Data Log that passes its output to the provided function rather than a file.
void AppendStringArray(int entry, std::span< const WPI_DataLog_String > arr, int64_t timestamp)
Appends a string array record to the log.
void AppendString(int entry, std::string_view value, int64_t timestamp)
Appends a string record to the log.
void AddSchema(std::string_view name, std::string_view type, std::span< const uint8_t > schema, int64_t timestamp=0)
Registers a data schema.
DataLog(wpi::Logger &msglog, std::string_view dir="", std::string_view filename="", double period=0.25, std::string_view extraHeader="")
Construct a new Data Log.
DataLog(DataLog &&)=delete
void Pause()
Pauses appending of data records to the log.
void AppendStringArray(int entry, std::span< const std::string_view > arr, int64_t timestamp)
Appends a string array record to the log.
bool HasSchema(std::string_view name) const
Returns whether there is a data schema already registered with the given name.
void SetFilename(std::string_view filename)
Change log filename.
DataLog(wpi::Logger &msglog, std::function< void(std::span< const uint8_t > data)> write, double period=0.25, std::string_view extraHeader="")
Construct a new Data Log that passes its output to the provided function rather than a file.
void AppendRaw2(int entry, std::span< const std::span< const uint8_t > > data, int64_t timestamp)
Appends a raw record to the log.
void Finish(int entry, int64_t timestamp=0)
Finish an entry.
void AppendDoubleArray(int entry, std::span< const double > arr, int64_t timestamp)
Appends a double array record to the log.
void Resume()
Resumes appending of data records to the log.
void AppendInteger(int entry, int64_t value, int64_t timestamp)
Appends an integer record to the log.
void AddProtobufSchema(ProtobufMessage< T > &msg, int64_t timestamp=0)
Registers a protobuf schema.
Definition: DataLog.h:250
void AddStructSchema(int64_t timestamp=0)
Registers a struct schema.
Definition: DataLog.h:269
void AppendBoolean(int entry, bool value, int64_t timestamp)
Appends a boolean record to the log.
Log array of double values.
Definition: DataLog.h:865
DoubleArrayLogEntry(DataLog &log, std::string_view name, int64_t timestamp=0)
Definition: DataLog.h:870
void Append(std::span< const double > arr, int64_t timestamp=0)
Appends a record to the log.
Definition: DataLog.h:883
void Append(std::initializer_list< double > arr, int64_t timestamp=0)
Appends a record to the log.
Definition: DataLog.h:893
DoubleArrayLogEntry()=default
DoubleArrayLogEntry(DataLog &log, std::string_view name, std::string_view metadata, int64_t timestamp=0)
Definition: DataLog.h:873
Log double values.
Definition: DataLog.h:674
DoubleLogEntry(DataLog &log, std::string_view name, std::string_view metadata, int64_t timestamp=0)
Definition: DataLog.h:681
void Append(double value, int64_t timestamp=0)
Appends a record to the log.
Definition: DataLog.h:691
DoubleLogEntry(DataLog &log, std::string_view name, int64_t timestamp=0)
Definition: DataLog.h:679
DoubleLogEntry()=default
Log array of float values.
Definition: DataLog.h:830
FloatArrayLogEntry(DataLog &log, std::string_view name, std::string_view metadata, int64_t timestamp=0)
Definition: DataLog.h:837
void Append(std::span< const float > arr, int64_t timestamp=0)
Appends a record to the log.
Definition: DataLog.h:847
void Append(std::initializer_list< float > arr, int64_t timestamp=0)
Appends a record to the log.
Definition: DataLog.h:857
FloatArrayLogEntry(DataLog &log, std::string_view name, int64_t timestamp=0)
Definition: DataLog.h:835
FloatArrayLogEntry()=default
Log float values.
Definition: DataLog.h:649
FloatLogEntry()=default
FloatLogEntry(DataLog &log, std::string_view name, int64_t timestamp=0)
Definition: DataLog.h:654
FloatLogEntry(DataLog &log, std::string_view name, std::string_view metadata, int64_t timestamp=0)
Definition: DataLog.h:656
void Append(float value, int64_t timestamp=0)
Appends a record to the log.
Definition: DataLog.h:666
Log array of integer values.
Definition: DataLog.h:794
IntegerArrayLogEntry(DataLog &log, std::string_view name, std::string_view metadata, int64_t timestamp=0)
Definition: DataLog.h:802
void Append(std::span< const int64_t > arr, int64_t timestamp=0)
Appends a record to the log.
Definition: DataLog.h:812
IntegerArrayLogEntry(DataLog &log, std::string_view name, int64_t timestamp=0)
Definition: DataLog.h:799
void Append(std::initializer_list< int64_t > arr, int64_t timestamp=0)
Appends a record to the log.
Definition: DataLog.h:822
IntegerArrayLogEntry()=default
Log integer values.
Definition: DataLog.h:624
IntegerLogEntry()=default
IntegerLogEntry(DataLog &log, std::string_view name, std::string_view metadata, int64_t timestamp=0)
Definition: DataLog.h:631
IntegerLogEntry(DataLog &log, std::string_view name, int64_t timestamp=0)
Definition: DataLog.h:629
void Append(int64_t value, int64_t timestamp=0)
Appends a record to the log.
Definition: DataLog.h:641
Log protobuf serializable objects.
Definition: DataLog.h:1041
ProtobufLogEntry(DataLog &log, std::string_view name, int64_t timestamp=0)
Definition: DataLog.h:1046
void Append(const T &data, int64_t timestamp=0)
Appends a record to the log.
Definition: DataLog.h:1061
ProtobufLogEntry(DataLog &log, std::string_view name, std::string_view metadata, int64_t timestamp=0)
Definition: DataLog.h:1048
ProtobufLogEntry()=default
Log arbitrary byte data.
Definition: DataLog.h:571
RawLogEntry(DataLog &log, std::string_view name, std::string_view metadata, int64_t timestamp=0)
Definition: DataLog.h:578
RawLogEntry(DataLog &log, std::string_view name, std::string_view metadata, std::string_view type, int64_t timestamp=0)
Definition: DataLog.h:581
static constexpr std::string_view kDataType
Definition: DataLog.h:573
RawLogEntry()=default
void Append(std::span< const uint8_t > data, int64_t timestamp=0)
Appends a record to the log.
Definition: DataLog.h:591
RawLogEntry(DataLog &log, std::string_view name, int64_t timestamp=0)
Definition: DataLog.h:576
Log array of string values.
Definition: DataLog.h:901
void Append(std::initializer_list< std::string_view > arr, int64_t timestamp=0)
Appends a record to the log.
Definition: DataLog.h:939
StringArrayLogEntry(DataLog &log, std::string_view name, std::string_view metadata, int64_t timestamp=0)
Definition: DataLog.h:909
void Append(std::span< const std::string > arr, int64_t timestamp=0)
Appends a record to the log.
Definition: DataLog.h:919
void Append(std::span< const std::string_view > arr, int64_t timestamp=0)
Appends a record to the log.
Definition: DataLog.h:929
StringArrayLogEntry()=default
StringArrayLogEntry(DataLog &log, std::string_view name, int64_t timestamp=0)
Definition: DataLog.h:906
Log string values.
Definition: DataLog.h:699
StringLogEntry(DataLog &log, std::string_view name, std::string_view metadata, int64_t timestamp=0)
Definition: DataLog.h:706
void Append(std::string_view value, int64_t timestamp=0)
Appends a record to the log.
Definition: DataLog.h:719
StringLogEntry(DataLog &log, std::string_view name, std::string_view metadata, std::string_view type, int64_t timestamp=0)
Definition: DataLog.h:709
StringLogEntry()=default
StringLogEntry(DataLog &log, std::string_view name, int64_t timestamp=0)
Definition: DataLog.h:704
Log raw struct serializable array of objects.
Definition: DataLog.h:988
void Append(std::span< const T > data, int64_t timestamp=0)
Appends a record to the log.
Definition: DataLog.h:1028
StructArrayLogEntry()=default
StructArrayLogEntry(DataLog &log, std::string_view name, std::string_view metadata, int64_t timestamp=0)
Definition: DataLog.h:996
StructArrayLogEntry(DataLog &log, std::string_view name, int64_t timestamp=0)
Definition: DataLog.h:993
void Append(U &&data, int64_t timestamp=0)
Appends a record to the log.
Definition: DataLog.h:1016
Log raw struct serializable objects.
Definition: DataLog.h:950
StructLogEntry(DataLog &log, std::string_view name, int64_t timestamp=0)
Definition: DataLog.h:955
StructLogEntry(DataLog &log, std::string_view name, std::string_view metadata, int64_t timestamp=0)
Definition: DataLog.h:957
StructLogEntry()=default
void Append(const T &data, int64_t timestamp=0)
Appends a record to the log.
Definition: DataLog.h:970
basic_string_view< char > string_view
Definition: core.h:501
auto ptr(T p) -> const void *
\rst Converts p to const void* for pointer formatting.
Definition: format.h:4100
dimensionless::scalar_t log(const ScalarUnit x) noexcept
Compute natural logarithm.
Definition: math.h:349
auto write(OutputIt out, const std::tm &time, const std::locale &loc, char format, char modifier=0) -> OutputIt
Definition: chrono.h:419
constexpr auto count() -> size_t
Definition: core.h:1203
state
Definition: core.h:2271
type
Definition: core.h:556
constexpr const char * name(const T &)
ControlRecordType
Definition: DataLog.h:54
@ kControlFinish
Definition: DataLog.h:56
@ kControlStart
Definition: DataLog.h:55
@ kControlSetMetadata
Definition: DataLog.h:57
Definition: ntcore_cpp.h:31
Definition: ntcore_cpp.h:26
constexpr bool is_constexpr(Lambda)
Definition: type_traits.h:81
uint64_t Now()
Return a value representing the current time in microseconds.
A datalog string (for use with string array).
Definition: DataLog.h:36
size_t len
Length.
Definition: DataLog.h:41
const char * str
Contents.
Definition: DataLog.h:38
Protobuf serialization template.
Definition: Protobuf.h:37
Struct serialization template.
Definition: Struct.h:37
::std::condition_variable condition_variable
Definition: condition_variable.h:16
::std::mutex mutex
Definition: mutex.h:17