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