Skip to content

Commit f1a8282

Browse files
authored
[wpiutil] Add DataLog and DataLogManager Stop() (#5860)
Restarting a stopped log results in creating a new log file with fresh copies of the same start records and schema data records. Also check to see if the file has been deleted or if the log file exceeds 1.8 GB, and start a new one.
1 parent 2a04e12 commit f1a8282

File tree

11 files changed

+394
-131
lines changed

11 files changed

+394
-131
lines changed

ntcoreffi/src/main/native/cpp/DataLogManager.cpp

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -264,12 +264,18 @@ Thread::~Thread() {
264264
void Thread::Main() {
265265
// based on free disk space, scan for "old" FRC_*.wpilog files and remove
266266
{
267-
uintmax_t freeSpace = fs::space(m_logDir).free;
267+
std::error_code ec;
268+
uintmax_t freeSpace;
269+
auto freeSpaceInfo = fs::space(m_logDir, ec);
270+
if (!ec) {
271+
freeSpace = freeSpaceInfo.available;
272+
} else {
273+
freeSpace = UINTMAX_MAX;
274+
}
268275
if (freeSpace < kFreeSpaceThreshold) {
269276
// Delete oldest FRC_*.wpilog files (ignore FRC_TBD_*.wpilog as we just
270277
// created one)
271278
std::vector<fs::directory_entry> entries;
272-
std::error_code ec;
273279
for (auto&& entry : fs::directory_iterator{m_logDir, ec}) {
274280
auto stem = entry.path().stem().string();
275281
if (wpi::starts_with(stem, "FRC_") &&
@@ -462,6 +468,9 @@ static Instance& GetInstance(std::string_view dir = "",
462468
std::string_view filename = "",
463469
double period = 0.25) {
464470
static Instance instance(dir, filename, period);
471+
if (!instance.owner) {
472+
instance.owner.Start(MakeLogDir(dir), filename, period);
473+
}
465474
return instance;
466475
}
467476

@@ -470,6 +479,12 @@ void DataLogManager::Start(std::string_view dir, std::string_view filename,
470479
GetInstance(dir, filename, period);
471480
}
472481

482+
void DataLogManager::Stop() {
483+
auto& inst = GetInstance();
484+
inst.owner.GetThread()->m_log.Stop();
485+
inst.owner.Stop();
486+
}
487+
473488
void DataLogManager::Log(std::string_view message) {
474489
GetInstance().owner.GetThread()->m_messageLog.Append(message);
475490
fmt::print("{}\n", message);
@@ -503,6 +518,10 @@ void DLM_Start(const char* dir, const char* filename, double period) {
503518
DataLogManager::Start(dir, filename, period);
504519
}
505520

521+
void DLM_Stop(void) {
522+
DataLogManager::Stop();
523+
}
524+
506525
void DLM_Log(const char* message) {
507526
DataLogManager::Log(message);
508527
}

ntcoreffi/src/main/native/include/DataLogManager.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,11 @@ class DataLogManager final {
5252
static void Start(std::string_view dir = "", std::string_view filename = "",
5353
double period = 0.25);
5454

55+
/**
56+
* Stop data log manager.
57+
*/
58+
static void Stop();
59+
5560
/**
5661
* Log a message to the "messages" entry. The message is also printed to
5762
* standard output (followed by a newline).
@@ -110,6 +115,11 @@ struct WPI_DataLog;
110115
*/
111116
void DLM_Start(const char* dir, const char* filename, double period);
112117

118+
/**
119+
* Stop data log manager.
120+
*/
121+
void DLM_Stop(void);
122+
113123
/**
114124
* Log a message to the "messages" entry. The message is also printed to
115125
* standard output (followed by a newline).

ntcoreffi/src/main/native/symbols.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ DLM_Log
44
DLM_LogNetworkTables
55
DLM_SignalNewDSDataOccur
66
DLM_Start
7+
DLM_Stop
78
NT_AddListener
89
NT_AddListenerMultiple
910
NT_AddListenerSingle
@@ -245,6 +246,7 @@ WPI_DataLog_Resume
245246
WPI_DataLog_SetFilename
246247
WPI_DataLog_SetMetadata
247248
WPI_DataLog_Start
249+
WPI_DataLog_Stop
248250
WPI_DestroyEvent
249251
WPI_DestroySemaphore
250252
WPI_DestroySignalObject

wpilibc/src/main/native/cpp/DataLogManager.cpp

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,12 +111,18 @@ Thread::~Thread() {
111111
void Thread::Main() {
112112
// based on free disk space, scan for "old" FRC_*.wpilog files and remove
113113
{
114-
uintmax_t freeSpace = fs::space(m_logDir).available;
114+
std::error_code ec;
115+
uintmax_t freeSpace;
116+
auto freeSpaceInfo = fs::space(m_logDir, ec);
117+
if (!ec) {
118+
freeSpace = freeSpaceInfo.available;
119+
} else {
120+
freeSpace = UINTMAX_MAX;
121+
}
115122
if (freeSpace < kFreeSpaceThreshold) {
116123
// Delete oldest FRC_*.wpilog files (ignore FRC_TBD_*.wpilog as we just
117124
// created one)
118125
std::vector<fs::directory_entry> entries;
119-
std::error_code ec;
120126
for (auto&& entry : fs::directory_iterator{m_logDir, ec}) {
121127
auto stem = entry.path().stem().string();
122128
if (wpi::starts_with(stem, "FRC_") &&
@@ -308,6 +314,9 @@ static Instance& GetInstance(std::string_view dir = "",
308314
std::string_view filename = "",
309315
double period = 0.25) {
310316
static Instance instance(dir, filename, period);
317+
if (!instance.owner) {
318+
instance.owner.Start(MakeLogDir(dir), filename, period);
319+
}
311320
return instance;
312321
}
313322

@@ -316,6 +325,12 @@ void DataLogManager::Start(std::string_view dir, std::string_view filename,
316325
GetInstance(dir, filename, period);
317326
}
318327

328+
void DataLogManager::Stop() {
329+
auto& inst = GetInstance();
330+
inst.owner.GetThread()->m_log.Stop();
331+
inst.owner.Stop();
332+
}
333+
319334
void DataLogManager::Log(std::string_view message) {
320335
GetInstance().owner.GetThread()->m_messageLog.Append(message);
321336
fmt::print("{}\n", message);

wpilibc/src/main/native/include/frc/DataLogManager.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@ class DataLogManager final {
4949
static void Start(std::string_view dir = "", std::string_view filename = "",
5050
double period = 0.25);
5151

52+
/**
53+
* Stop data log manager.
54+
*/
55+
static void Stop();
56+
5257
/**
5358
* Log a message to the "messages" entry. The message is also printed to
5459
* standard output (followed by a newline).

wpilibj/src/main/java/edu/wpi/first/wpilibj/DataLogManager.java

Lines changed: 42 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,10 @@
4141
*/
4242
public final class DataLogManager {
4343
private static DataLog m_log;
44+
private static boolean m_stopped;
4445
private static String m_logDir;
4546
private static boolean m_filenameOverride;
46-
private static final Thread m_thread;
47+
private static Thread m_thread;
4748
private static final ZoneId m_utc = ZoneId.of("UTC");
4849
private static final DateTimeFormatter m_timeFormatter =
4950
DateTimeFormatter.ofPattern("yyyyMMdd_HHmmss").withZone(m_utc);
@@ -59,11 +60,6 @@ public final class DataLogManager {
5960

6061
private DataLogManager() {}
6162

62-
static {
63-
m_thread = new Thread(DataLogManager::logMain, "DataLogDS");
64-
m_thread.setDaemon(true);
65-
}
66-
6763
/** Start data log manager with default directory location. */
6864
public static synchronized void start() {
6965
start("", "", 0.25);
@@ -100,33 +96,52 @@ public static synchronized void start(String dir, String filename) {
10096
* tradeoff
10197
*/
10298
public static synchronized void start(String dir, String filename, double period) {
103-
if (m_log != null) {
104-
return;
105-
}
106-
m_logDir = makeLogDir(dir);
107-
m_filenameOverride = !filename.isEmpty();
99+
if (m_log == null) {
100+
m_logDir = makeLogDir(dir);
101+
m_filenameOverride = !filename.isEmpty();
108102

109-
// Delete all previously existing FRC_TBD_*.wpilog files. These only exist when the robot
110-
// never connects to the DS, so they are very unlikely to have useful data and just clutter
111-
// the filesystem.
112-
File[] files =
113-
new File(m_logDir)
114-
.listFiles((d, name) -> name.startsWith("FRC_TBD_") && name.endsWith(".wpilog"));
115-
if (files != null) {
116-
for (File file : files) {
117-
if (!file.delete()) {
118-
System.err.println("DataLogManager: could not delete " + file);
103+
// Delete all previously existing FRC_TBD_*.wpilog files. These only exist when the robot
104+
// never connects to the DS, so they are very unlikely to have useful data and just clutter
105+
// the filesystem.
106+
File[] files =
107+
new File(m_logDir)
108+
.listFiles((d, name) -> name.startsWith("FRC_TBD_") && name.endsWith(".wpilog"));
109+
if (files != null) {
110+
for (File file : files) {
111+
if (!file.delete()) {
112+
System.err.println("DataLogManager: could not delete " + file);
113+
}
119114
}
120115
}
116+
m_log = new DataLog(m_logDir, makeLogFilename(filename), period);
117+
m_messageLog = new StringLogEntry(m_log, "messages");
118+
119+
// Log all NT entries and connections
120+
if (m_ntLoggerEnabled) {
121+
startNtLog();
122+
}
123+
} else if (m_stopped) {
124+
m_log.setFilename(makeLogFilename(filename));
125+
m_log.resume();
126+
m_stopped = false;
121127
}
122128

123-
m_log = new DataLog(m_logDir, makeLogFilename(filename), period);
124-
m_messageLog = new StringLogEntry(m_log, "messages");
125-
m_thread.start();
129+
if (m_thread == null) {
130+
m_thread = new Thread(DataLogManager::logMain, "DataLogDS");
131+
m_thread.setDaemon(true);
132+
m_thread.start();
133+
}
134+
}
126135

127-
// Log all NT entries and connections
128-
if (m_ntLoggerEnabled) {
129-
startNtLog();
136+
/** Stop data log manager. */
137+
public static synchronized void stop() {
138+
if (m_thread != null) {
139+
m_thread.interrupt();
140+
m_thread = null;
141+
}
142+
if (m_log != null) {
143+
m_log.stop();
144+
m_stopped = true;
130145
}
131146
}
132147

wpiutil/src/main/java/edu/wpi/first/util/datalog/DataLog.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,11 +106,20 @@ public void pause() {
106106
DataLogJNI.pause(m_impl);
107107
}
108108

109-
/** Resumes appending of data records to the log. */
109+
/**
110+
* Resumes appending of data records to the log. If called after stop(), opens a new file (with
111+
* random name if SetFilename was not called after stop()) and appends Start records and schema
112+
* data values for all previously started entries and schemas.
113+
*/
110114
public void resume() {
111115
DataLogJNI.resume(m_impl);
112116
}
113117

118+
/** Stops appending all records to the log, and closes the log file. */
119+
public void stop() {
120+
DataLogJNI.stop(m_impl);
121+
}
122+
114123
/**
115124
* Returns whether there is a data schema already registered with the given name.
116125
*

wpiutil/src/main/java/edu/wpi/first/util/datalog/DataLogJNI.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ public class DataLogJNI extends WPIUtilJNI {
1818

1919
static native void resume(long impl);
2020

21+
static native void stop(long impl);
22+
2123
static native void addSchema(long impl, String name, String type, byte[] schema, long timestamp);
2224

2325
static native void addSchemaString(

0 commit comments

Comments
 (0)