mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-07-04 03:11:43 +00:00
Add logging framework.
DEBUG messages are completely optimized out if NDEBUG is defined.
This commit is contained in:
@@ -35,6 +35,19 @@ enum NT_EntryFlags {
|
|||||||
NT_PERSISTENT = 0x01
|
NT_PERSISTENT = 0x01
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** NetworkTables logging levels. */
|
||||||
|
enum NT_LogLevel {
|
||||||
|
NT_LOG_CRITICAL = 50,
|
||||||
|
NT_LOG_ERROR = 40,
|
||||||
|
NT_LOG_WARNING = 30,
|
||||||
|
NT_LOG_INFO = 20,
|
||||||
|
NT_LOG_DEBUG = 10,
|
||||||
|
NT_LOG_DEBUG1 = 9,
|
||||||
|
NT_LOG_DEBUG2 = 8,
|
||||||
|
NT_LOG_DEBUG3 = 7,
|
||||||
|
NT_LOG_DEBUG4 = 6
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Structures
|
* Structures
|
||||||
*/
|
*/
|
||||||
@@ -309,6 +322,11 @@ void NT_DisposeConnectionInfoArray(struct NT_ConnectionInfo *arr, size_t count);
|
|||||||
/* timestamp */
|
/* timestamp */
|
||||||
unsigned long long NT_Now(void);
|
unsigned long long NT_Now(void);
|
||||||
|
|
||||||
|
/* logging */
|
||||||
|
typedef void (*NT_LogFunc)(unsigned int level, const char *file,
|
||||||
|
unsigned int line, const char *msg);
|
||||||
|
void NT_SetLogger(NT_LogFunc func, unsigned int min_level);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -220,6 +220,11 @@ const char* LoadPersistent(
|
|||||||
/* timestamp */
|
/* timestamp */
|
||||||
unsigned long long Now();
|
unsigned long long Now();
|
||||||
|
|
||||||
|
/* logging */
|
||||||
|
typedef std::function<void(unsigned int level, const char* file,
|
||||||
|
unsigned int line, const char* msg)> LogFunc;
|
||||||
|
void SetLogger(LogFunc func, unsigned int min_level);
|
||||||
|
|
||||||
} // namespace nt
|
} // namespace nt
|
||||||
|
|
||||||
#endif /* NTCORE_CPP_H_ */
|
#endif /* NTCORE_CPP_H_ */
|
||||||
|
|||||||
@@ -12,17 +12,10 @@
|
|||||||
|
|
||||||
#include "tcpsockets/TCPAcceptor.h"
|
#include "tcpsockets/TCPAcceptor.h"
|
||||||
#include "tcpsockets/TCPConnector.h"
|
#include "tcpsockets/TCPConnector.h"
|
||||||
|
#include "Log.h"
|
||||||
|
|
||||||
using namespace nt;
|
using namespace nt;
|
||||||
|
|
||||||
inline void DEBUG(const char* str, ...) {
|
|
||||||
va_list args;
|
|
||||||
va_start(args, str);
|
|
||||||
vfprintf(stderr, str, args);
|
|
||||||
fputc('\n', stderr);
|
|
||||||
va_end(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
ATOMIC_STATIC_INIT(Dispatcher)
|
ATOMIC_STATIC_INIT(Dispatcher)
|
||||||
|
|
||||||
Dispatcher::Dispatcher()
|
Dispatcher::Dispatcher()
|
||||||
@@ -302,7 +295,7 @@ bool Dispatcher::ClientHandshake(
|
|||||||
if (msg->Is(Message::kServerHelloDone)) break;
|
if (msg->Is(Message::kServerHelloDone)) break;
|
||||||
if (!msg->Is(Message::kEntryAssign)) {
|
if (!msg->Is(Message::kEntryAssign)) {
|
||||||
// unexpected message
|
// unexpected message
|
||||||
DEBUG("client: received message (%d) other than entry assignment during initial handshake", msg->type());
|
DEBUG("client: received message (" << msg->type() << ") other than entry assignment during initial handshake");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
incoming.emplace_back(std::move(msg));
|
incoming.emplace_back(std::move(msg));
|
||||||
@@ -388,7 +381,7 @@ bool Dispatcher::ServerHandshake(
|
|||||||
if (msg->Is(Message::kClientHelloDone)) break;
|
if (msg->Is(Message::kClientHelloDone)) break;
|
||||||
if (!msg->Is(Message::kEntryAssign)) {
|
if (!msg->Is(Message::kEntryAssign)) {
|
||||||
// unexpected message
|
// unexpected message
|
||||||
DEBUG("server: received message (%d) other than entry assignment during initial handshake", msg->type());
|
DEBUG("server: received message (" << msg->type() << ") other than entry assignment during initial handshake");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
incoming.push_back(msg);
|
incoming.push_back(msg);
|
||||||
|
|||||||
16
src/Log.cpp
Normal file
16
src/Log.cpp
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
/* Copyright (c) FIRST 2015. All Rights Reserved. */
|
||||||
|
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||||
|
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||||
|
/* the project. */
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "Log.h"
|
||||||
|
|
||||||
|
using namespace nt;
|
||||||
|
|
||||||
|
ATOMIC_STATIC_INIT(Logger)
|
||||||
|
|
||||||
|
Logger::Logger() : m_min_level(100) {}
|
||||||
|
|
||||||
|
Logger::~Logger() {}
|
||||||
83
src/Log.h
Normal file
83
src/Log.h
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
/* Copyright (c) FIRST 2015. All Rights Reserved. */
|
||||||
|
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||||
|
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||||
|
/* the project. */
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef NT_LOG_H_
|
||||||
|
#define NT_LOG_H_
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "atomic_static.h"
|
||||||
|
#include "ntcore_c.h"
|
||||||
|
|
||||||
|
namespace nt {
|
||||||
|
|
||||||
|
class Logger {
|
||||||
|
public:
|
||||||
|
static Logger& GetInstance() {
|
||||||
|
ATOMIC_STATIC(Logger, instance);
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
~Logger();
|
||||||
|
|
||||||
|
typedef std::function<void(unsigned int level, const char* file,
|
||||||
|
unsigned int line, const char* msg)> LogFunc;
|
||||||
|
|
||||||
|
void SetLogger(LogFunc func) { m_func = func; }
|
||||||
|
|
||||||
|
void set_min_level(unsigned int level) { m_min_level = level; }
|
||||||
|
unsigned int min_level() const { return m_min_level; }
|
||||||
|
|
||||||
|
void Log(unsigned int level, const char* file, unsigned int line,
|
||||||
|
const char* msg) {
|
||||||
|
if (!m_func || level < m_min_level) return;
|
||||||
|
m_func(level, file, line, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HasLogger() const { return m_func != nullptr; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
Logger();
|
||||||
|
|
||||||
|
LogFunc m_func;
|
||||||
|
unsigned int m_min_level;
|
||||||
|
|
||||||
|
ATOMIC_STATIC_DECL(Logger)
|
||||||
|
};
|
||||||
|
|
||||||
|
#define LOG(level, x) \
|
||||||
|
do { \
|
||||||
|
Logger& logger = Logger::GetInstance(); \
|
||||||
|
if (logger.min_level() <= level && logger.HasLogger()) { \
|
||||||
|
std::ostringstream oss; \
|
||||||
|
oss << x; \
|
||||||
|
logger.Log(level, __FILE__, __LINE__, oss.str().c_str()); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define ERROR(x) LOG(NT_LOG_ERROR, x)
|
||||||
|
#define WARNING(x) LOG(NT_LOG_WARNING, x)
|
||||||
|
#define INFO(x) LOG(NT_LOG_INFO, x)
|
||||||
|
|
||||||
|
#ifdef NDEBUG
|
||||||
|
#define DEBUG(x)
|
||||||
|
#define DEBUG1(x)
|
||||||
|
#define DEBUG2(x)
|
||||||
|
#define DEBUG3(x)
|
||||||
|
#define DEBUG4(x)
|
||||||
|
#else
|
||||||
|
#define DEBUG(x) LOG(NT_LOG_DEBUG, x)
|
||||||
|
#define DEBUG1(x) LOG(NT_LOG_DEBUG1, x)
|
||||||
|
#define DEBUG2(x) LOG(NT_LOG_DEBUG2, x)
|
||||||
|
#define DEBUG3(x) LOG(NT_LOG_DEBUG3, x)
|
||||||
|
#define DEBUG4(x) LOG(NT_LOG_DEBUG4, x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} // namespace nt
|
||||||
|
|
||||||
|
#endif // NT_LOG_H_
|
||||||
@@ -8,20 +8,13 @@
|
|||||||
#include "NetworkConnection.h"
|
#include "NetworkConnection.h"
|
||||||
|
|
||||||
#include "tcpsockets/TCPStream.h"
|
#include "tcpsockets/TCPStream.h"
|
||||||
|
#include "Log.h"
|
||||||
#include "raw_socket_istream.h"
|
#include "raw_socket_istream.h"
|
||||||
#include "WireDecoder.h"
|
#include "WireDecoder.h"
|
||||||
#include "WireEncoder.h"
|
#include "WireEncoder.h"
|
||||||
|
|
||||||
using namespace nt;
|
using namespace nt;
|
||||||
|
|
||||||
inline void DEBUG(const char* str, ...) {
|
|
||||||
va_list args;
|
|
||||||
va_start(args, str);
|
|
||||||
vfprintf(stderr, str, args);
|
|
||||||
fputc('\n', stderr);
|
|
||||||
va_end(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
NetworkConnection::NetworkConnection(std::unique_ptr<TCPStream> stream,
|
NetworkConnection::NetworkConnection(std::unique_ptr<TCPStream> stream,
|
||||||
HandshakeFunc handshake,
|
HandshakeFunc handshake,
|
||||||
Message::GetEntryTypeFunc get_entry_type,
|
Message::GetEntryTypeFunc get_entry_type,
|
||||||
@@ -81,8 +74,8 @@ void NetworkConnection::ReadThreadMain() {
|
|||||||
[&] {
|
[&] {
|
||||||
decoder.set_proto_rev(m_proto_rev);
|
decoder.set_proto_rev(m_proto_rev);
|
||||||
auto msg = Message::Read(decoder, m_get_entry_type);
|
auto msg = Message::Read(decoder, m_get_entry_type);
|
||||||
if (!msg)
|
if (!msg && decoder.error())
|
||||||
DEBUG("error reading in handshake: %s", decoder.error());
|
DEBUG("error reading in handshake: " << decoder.error());
|
||||||
return msg;
|
return msg;
|
||||||
},
|
},
|
||||||
[&](llvm::ArrayRef<std::shared_ptr<Message>> msgs) {
|
[&](llvm::ArrayRef<std::shared_ptr<Message>> msgs) {
|
||||||
@@ -116,11 +109,11 @@ void NetworkConnection::WriteThreadMain() {
|
|||||||
|
|
||||||
while (m_active) {
|
while (m_active) {
|
||||||
auto msgs = m_outgoing.pop();
|
auto msgs = m_outgoing.pop();
|
||||||
DEBUG("write thread woke up");
|
DEBUG4("write thread woke up");
|
||||||
if (msgs.empty()) break;
|
if (msgs.empty()) break;
|
||||||
encoder.set_proto_rev(m_proto_rev);
|
encoder.set_proto_rev(m_proto_rev);
|
||||||
encoder.Reset();
|
encoder.Reset();
|
||||||
DEBUG("sending %d messages", msgs.size());
|
DEBUG4("sending " << msgs.size() << " messages");
|
||||||
for (auto& msg : msgs) {
|
for (auto& msg : msgs) {
|
||||||
if (msg) msg->Write(encoder);
|
if (msg) msg->Write(encoder);
|
||||||
}
|
}
|
||||||
@@ -128,7 +121,7 @@ void NetworkConnection::WriteThreadMain() {
|
|||||||
if (!m_stream) break;
|
if (!m_stream) break;
|
||||||
if (encoder.size() == 0) continue;
|
if (encoder.size() == 0) continue;
|
||||||
if (m_stream->send(encoder.data(), encoder.size(), &err) == 0) break;
|
if (m_stream->send(encoder.data(), encoder.size(), &err) == 0) break;
|
||||||
DEBUG("sent %d bytes", encoder.size());
|
DEBUG4("sent " << encoder.size() << " bytes");
|
||||||
}
|
}
|
||||||
m_state = static_cast<int>(kDead);
|
m_state = static_cast<int>(kDead);
|
||||||
m_active = false;
|
m_active = false;
|
||||||
|
|||||||
@@ -12,11 +12,10 @@
|
|||||||
|
|
||||||
#include "llvm/StringExtras.h"
|
#include "llvm/StringExtras.h"
|
||||||
#include "Base64.h"
|
#include "Base64.h"
|
||||||
|
#include "Log.h"
|
||||||
|
|
||||||
using namespace nt;
|
using namespace nt;
|
||||||
|
|
||||||
#define DEBUG(str) puts(str)
|
|
||||||
|
|
||||||
ATOMIC_STATIC_INIT(Storage)
|
ATOMIC_STATIC_INIT(Storage)
|
||||||
|
|
||||||
Storage::Storage() {}
|
Storage::Storage() {}
|
||||||
|
|||||||
@@ -288,6 +288,10 @@ const char *NT_LoadPersistent(const char *filename,
|
|||||||
* Utility Functions
|
* Utility Functions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
void NT_SetLogger(NT_LogFunc func, unsigned int min_level) {
|
||||||
|
nt::SetLogger(func, min_level);
|
||||||
|
}
|
||||||
|
|
||||||
void NT_DisposeValue(NT_Value *value) {
|
void NT_DisposeValue(NT_Value *value) {
|
||||||
switch (value->type) {
|
switch (value->type) {
|
||||||
case NT_UNASSIGNED:
|
case NT_UNASSIGNED:
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
#include "Dispatcher.h"
|
#include "Dispatcher.h"
|
||||||
|
#include "Log.h"
|
||||||
#include "Storage.h"
|
#include "Storage.h"
|
||||||
|
|
||||||
namespace nt {
|
namespace nt {
|
||||||
@@ -173,4 +174,10 @@ const char* LoadPersistent(
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetLogger(LogFunc func, unsigned int min_level) {
|
||||||
|
Logger& logger = Logger::GetInstance();
|
||||||
|
logger.SetLogger(func);
|
||||||
|
logger.set_min_level(min_level);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace nt
|
} // namespace nt
|
||||||
|
|||||||
Reference in New Issue
Block a user