RemoteLogRK
|
Remote logging class. Typically created a single global variable. More...
#include <RemoteLogRK.h>
Public Member Functions | |
RemoteLog (uint8_t *buf, size_t bufLen, LogLevel level=LOG_LEVEL_INFO, LogCategoryFilters filters={}) | |
Constructor. More... | |
virtual | ~RemoteLog () |
RemoteLog & | withServer (RemoteLogServer *server) |
Adds a specific server subclass. More... | |
void | setup () |
You must call setup() from the app setup(). More... | |
void | loop () |
You must call loop() from the app loop() More... | |
virtual size_t | write (uint8_t) |
Virtual override in class Print for the StreamLogHandler to write data to the log. | |
RemoteLogBufHeader * | getBufHeader () |
Get pointer to the log message buffer as a RemoteLogBufHeader *. More... | |
uint8_t * | getBufData () |
Gets a pointer to the data area of the log message buffer, right after the RemoteLogBufHeader. | |
size_t | getBufDataLen () const |
Gets the number of bytes of log message data available, taking into account the RemoteLogBufHeader. | |
bool | readNoCopy (size_t &readIndex, uint8_t *&readBuf, size_t &readBufLen) |
Read log messages without copying. More... | |
bool | readLines (size_t &readIndex, uint8_t *readBuf, size_t &readBufLen, bool oneLine=false) |
Copy lines out of the buffer. More... | |
void | lock () |
Mutex lock, used to safely access the buffer. More... | |
bool | trylock () |
Mutex lock, used to safely access the buffer. More... | |
void | unlock () |
Mutex unlock, used release the mutex obtained by lock() or trylock() | |
void | systemEventHandler (system_event_t event, int data, void *moreData) |
System event handler callback. More... | |
Static Public Member Functions | |
static void | systemEventHandlerStatic (system_event_t event, int data, void *moreData) |
System event handler callback (static) More... | |
static RemoteLog * | getInstance () |
Get the singleton instance of this class. More... | |
Static Public Attributes | |
static const uint32_t | BUF_MAGIC = 0x312ad071 |
Magic bytes stored in the retained memory structure. | |
Protected Member Functions | |
RemoteLog (const RemoteLog &)=delete | |
This class is not copyable. | |
RemoteLog & | operator= (const RemoteLog &)=delete |
This class is not copyable. | |
Protected Attributes | |
uint8_t * | buf |
Pointer to the buffer. More... | |
size_t | bufLen |
Size of the buffer, including both the RemoteLogBufHeader and the data. | |
RemoteLogServer * | servers [REMOTELOG_MAX_SERVERS] |
Server object instances, added using withServer() | |
size_t | numServers = 0 |
Number of servers assigned. More... | |
os_mutex_t | mutex = 0 |
Mutex for preventing simultaneous access to the buffer from multiple threads. | |
Static Protected Attributes | |
static RemoteLog * | instance |
Singleton instance of this class. | |
Remote logging class. Typically created a single global variable.
You can only have one instance of this class per application.
RemoteLog::RemoteLog | ( | uint8_t * | buf, |
size_t | bufLen, | ||
LogLevel | level = LOG_LEVEL_INFO , |
||
LogCategoryFilters | filters = {} |
||
) |
Constructor.
buf | Buffer to store log messages. Often uses retained memory, but not required. |
bufLen | Buffer length. Recommended size is 2560 or more. Minimum size is 256 bytes. |
level | Default log level. Default is is LOG_LEVEL_INFO. Using LOG_LEVEL_TRACE may results in an excessive number of log messages. |
filters | Optional log category filters to control the verbosity by category. |
There is no default constructor. You must specify the parameters at construction. You typically instantiate this class as a global variable.
|
virtual |
Destructor | As this class is normally created as a global variable, it's typically never deleted. |
|
inline |
Get pointer to the log message buffer as a RemoteLogBufHeader *.
This structure is initialized during object construction so it should always be valid.
|
inlinestatic |
Get the singleton instance of this class.
This object is normally instantiated as a single instance global variable. The constructor saves the object pointer so it can be retrieved using getInstance(). This necessarily means you can only have one instance of this class, but it doesn't make sense to have more than one RemoteLog. You can have multiple servers.
|
inline |
Mutex lock, used to safely access the buffer.
Since the buffer is written to by the write() method which may be called from another thread, a mutex is needed to safely access it from loop() as well.
Be sure to balance every call to lock() with an unlock(). Avoid locking for extended periods of time as this will block logging from other threads, which may cause other threads to block.
void RemoteLog::loop | ( | ) |
bool RemoteLog::readLines | ( | size_t & | readIndex, |
uint8_t * | readBuf, | ||
size_t & | readBufLen, | ||
bool | oneLine = false |
||
) |
Copy lines out of the buffer.
readIndex | Used to keep track of the point you are reading from. Set to 0 on initial call. Unlike readNoCopy, readLines does increment readIndex. |
readBuf | Pointer to a buffer to copy data to. |
readBufLen | On input, the maximum number of bytes you want. On output, the number of bytes copied. |
oneLine | If true, only copy one line of data. If false (default), copy as many full lines as will fit. |
If readBufLen on input is smaller than an entire line, the line will be returned in incomplete pieces.
Do not call lock() and unlock() around this call. It's handled internally.
bool RemoteLog::readNoCopy | ( | size_t & | readIndex, |
uint8_t *& | readBuf, | ||
size_t & | readBufLen | ||
) |
Read log messages without copying.
readIndex | Used to keep track of the point you are reading from. Set to 0 on initial call. It will be updated internally, however you must increment it by the amount you have consumed before calling again. See below. |
readBuf | Filled in with a pointer to a uint8_t where the data resides. |
readBufLen | On input, the maximum number of bytes you want. On output, the number of bytes available. |
This method is designed to efficiently handle writing to TCP streams. It may be easier to use readLines() for other applications. The reads will be not be aligned to lines with this function, and individual log messages may be split into two pieces. The idea is that you call readNoCopy() which returns a pointer to the internal buffer in retained memory along with the amount of data you available, limited to the amount you want. Since the buffer is circular, it will also be limited to the point where the buffer wraps around. You then use this data, such as writing to a TCP stream, or a file on a file system. For things that may not consume all of the data, such as TCP with a full buffer and no blocking, you don't have to use all of the data. Increment readIndex by the amount you consumed, up to readBufLen, if you've consumed the entire buffer.
Note: You must lock() and unlock() this object surrounding a call to readNoCopy(). It's not built into this function because you don't want to release it until you've consumed the data you are planning to consume. In the TCP example above, you'd lock surrounding the calls to both readNoCopy() and your TCP write() call.
void RemoteLog::setup | ( | ) |
You must call setup() from the app setup().
Call withServer() to add all servers before setup()!
void RemoteLog::systemEventHandler | ( | system_event_t | event, |
int | data, | ||
void * | moreData | ||
) |
System event handler callback.
The RemoteLog registers for reset events and passes them to servers. This is used by the RemoteLogTCPServer to stop the connection before reset. Otherwise, the client may not realize that the server has gone away.
|
static |
System event handler callback (static)
Finds the object instance using getInstance() as it's a singleton.
|
inline |
Mutex lock, used to safely access the buffer.
The trylock() method returns true if the mutex was locked (and must be unlocked later)
RemoteLog & RemoteLog::withServer | ( | RemoteLogServer * | server | ) |
Adds a specific server subclass.
By default, the RemoteLog doesn't send the data anywhere. You need to associate it with a specific server class such as RemoteLogTCPServer or RemoteLogUDPMulticastServer depending on what you want to do with the log messages. This method registers the server to add.
You can add multiple servers if desired. You must add the servers before calling the setup() method. You cannot remove servers once added. Adding servers after setup is not supported, either.
The maximum number of servers you can add is REMOTELOG_MAX_SERVERS.
|
protected |
Pointer to the buffer.
Begins with a RemoteLogBufHeader and has a circular buffer of data after it
|
protected |
Number of servers assigned.
0 = no servers, 1 = index 0 is filled in, ...
Will be at most REMOTELOG_MAX_SERVERS.