30#include <interfaces/atomic_ops.h>
33#include <tscpp/buffer.h>
53 for (fileNumber = 0; fileNumber < (int)maxFilenameNumber; fileNumber++)
56 filename = getFileName(fileNumber);
58 if (stat(filename.c_str(), &st) != 0)
61 if (fileNumber == maxFilenameNumber - 1)
62 TRACE(
"Too many log files, appending data to last\n");
65 file = fopen(filename.c_str(),
"ab");
69 TRACE(
"Error opening %s file\n", filename.c_str());
78 packTh = Thread::create(packThreadLauncher, STACK_MIN_FOR_SKYWARD, 1,
this,
83 TRACE(
"Error creating pack thread\n");
87 writeTh = Thread::create(writeThreadLauncher, STACK_MIN_FOR_SKYWARD, 1,
88 this, Thread::JOINABLE);
91 fullRecordsQueue.put(
nullptr);
95 while (fullBufferList.front() !=
nullptr)
97 emptyBufferList.push(fullBufferList.front());
100 fullBufferList.pop();
102 TRACE(
"Error creating write thread\n");
113 if (started ==
false)
119 fullRecordsQueue.put(
nullptr);
133 bool result = ofstream(
"/sd/test").good();
134 std::remove(
"/sd/test");
174 for (
unsigned int i = 0; i < numRecords; i++)
175 emptyRecordsQueue.put(
new Record);
178 for (
unsigned int i = 0; i < numBuffers; i++)
179 emptyBufferList.push(
new Buffer);
182string Logger::getFileName(
int logNumber)
185 sprintf(filename,
"/sd/log%02d.dat", logNumber);
187 return string(filename);
190void Logger::packThreadLauncher(
void* argv)
192 reinterpret_cast<Logger*
>(argv)->packThread();
195void Logger::writeThreadLauncher(
void* argv)
197 reinterpret_cast<Logger*
>(argv)->writeThread();
200void Logger::packThread()
220 Buffer* buffer =
nullptr;
222 Lock<FastMutex>
l(mutex);
224 while (emptyBufferList.empty())
226 buffer = emptyBufferList.front();
227 emptyBufferList.pop();
233 Record* record =
nullptr;
234 fullRecordsQueue.get(record);
237 if (record ==
nullptr)
239 Lock<FastMutex>
l(mutex);
240 fullBufferList.push(buffer);
241 fullBufferList.push(
nullptr);
247 memcpy(buffer->data + buffer->size, record->data, record->size);
248 buffer->size += record->size;
249 emptyRecordsQueue.put(record);
250 }
while (bufferSize - buffer->size >= maxRecordSize);
253 Lock<FastMutex>
l(mutex);
255 fullBufferList.push(buffer);
263 TRACE(
"Error: packThread failed due to an exception: %s\n", e.what());
267void Logger::writeThread()
275 Buffer* buffer =
nullptr;
277 Lock<FastMutex>
l(mutex);
279 while (fullBufferList.empty())
281 buffer = fullBufferList.front();
282 fullBufferList.pop();
287 if (buffer ==
nullptr)
291 using namespace std::chrono;
292 auto start = system_clock::now();
294 size_t result = fwrite(buffer->data, 1, buffer->size, file);
295 if (result != buffer->size)
307 auto interval = system_clock::now() -
start;
309 duration_cast<milliseconds>(interval).count();
314 Lock<FastMutex>
l(mutex);
317 emptyBufferList.push(buffer);
324 TRACE(
"Error: writeThread failed due to an exception: %s\n", e.what());
328LoggerResult Logger::logImpl(
const char* name,
const void* data,
331 if (started ==
false)
341 Record* record =
nullptr;
346 FastInterruptDisableLock dLock;
347 if (emptyRecordsQueue.IRQget(record) ==
false)
356 tscpp::serializeImpl(record->data, maxRecordSize, name, data, size);
359 if (result == tscpp::BufferTooSmall)
361 emptyRecordsQueue.put(record);
363 TRACE(
"The current record size is not enough to store %s\n", name);
367 record->size = result;
371 fullRecordsQueue.put(record);
LoggerResult log(const T &t)
Call this function to log a class.
void logStats()
Log logger stats using the logger itself.
std::string getCurrentFileName()
int getCurrentLogNumber()
static bool testSDCard()
Tests if the Logger can write to the SD card by opening a file.
void stop()
Call this function to stop the logger.
bool start()
Call this function to start the logger.
static StackLogger & getInstance()
uint64_t getTimestamp()
Returns the current timer value in microseconds.
This file includes all the types the logdecoder script will decode.
LoggerResult
Possible outcomes of Logger::log().
@ Dropped
Buffers are currently full, data will not be written. Sorry.
@ Queued
Data has been accepted by the logger and will be written.
@ TooLarge
Data is too large to be logged. Increase maxRecordSize.
@ Ignored
Logger is currently stopped, data will not be written.
Statistics for the logger.
int droppedSamples
Number of dropped samples due to fifo full.
int logNumber
Number of dropped samples because they where too large.
int averageWriteTime
Average time for an fwrite() of a buffer.
int maxWriteTime
Max time for an fwrite() of a buffer.
int lastWriteError
Error of the last fwrite() that failed.
int buffersWritten
Number of buffers written to disk.
int buffersFilled
Number of buffers filled.
int writesFailed
Number of fwrite() that failed.
int queuedSamples
Number of samples written to buffer.