JavaCPP Presets for libfreenect2 providing Java bindings for Kinect for Windows v2 device drivers
—
Configurable logging system with multiple severity levels and custom logger support. This module enables debugging, monitoring, and troubleshooting of libfreenect2 operations.
Base logging interface that can be extended for custom logging implementations.
/**
* Provide interfaces to receive log messages.
* You can inherit this class and implement your custom logger.
*/
abstract class Logger {
// Logging level constants
/** No logging output */
static final int None = 0;
/** Error messages only */
static final int Error = 1;
/** Error and warning messages */
static final int Warning = 2;
/** Error, warning, and info messages */
static final int Info = 3;
/** All messages including debug output */
static final int Debug = 4;
/**
* Default logging level (Info), or overridden by environment variable.
* LIBFREENECT2_LOGGER_LEVEL can contain a case-insensitive name of level.
*/
@Cast("libfreenect2::Logger::Level") static int getDefaultLevel();
/**
* Convert logging level to a human-readable name
*/
@StdString static BytePointer level2str(@Cast("libfreenect2::Logger::Level") int level);
/**
* Get the level of the logger; the level is immutable
*/
@Cast("libfreenect2::Logger::Level") abstract int level();
/**
* libfreenect2 calls this function to output all log messages
* @param level Message severity level
* @param message Log message content
*/
void log(@Cast("libfreenect2::Logger::Level") int level, @StdString BytePointer message);
void log(@Cast("libfreenect2::Logger::Level") int level, @StdString String message);
}Usage Examples:
// Check default logging level
int defaultLevel = Logger.getDefaultLevel();
System.out.println("Default log level: " + Logger.level2str(defaultLevel).getString());
// The library automatically creates a console logger, but you can customize itImplement custom loggers for different output destinations and formats.
Usage Examples:
// Custom file logger implementation
class FileLogger extends Logger {
private final int logLevel;
private final PrintWriter writer;
public FileLogger(int level, String filename) throws IOException {
this.logLevel = level;
this.writer = new PrintWriter(new FileWriter(filename, true));
}
@Override
public int level() {
return logLevel;
}
@Override
public void log(int level, String message) {
if (level <= this.logLevel) {
String timestamp = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
String levelName = Logger.level2str(level).getString();
writer.println("[" + timestamp + "] " + levelName + ": " + message);
writer.flush();
}
}
@Override
public void log(int level, BytePointer message) {
log(level, message.getString());
}
public void close() {
writer.close();
}
}
// Custom console logger with formatting
class FormattedConsoleLogger extends Logger {
private final int logLevel;
public FormattedConsoleLogger(int level) {
this.logLevel = level;
}
@Override
public int level() {
return logLevel;
}
@Override
public void log(int level, String message) {
if (level <= this.logLevel) {
String levelName = Logger.level2str(level).getString();
String prefix = "";
switch (level) {
case Logger.Error:
prefix = "ERROR ";
break;
case Logger.Warning:
prefix = "WARN ";
break;
case Logger.Info:
prefix = "INFO ";
break;
case Logger.Debug:
prefix = "DEBUG ";
break;
}
System.out.println("[libfreenect2] " + prefix + message);
}
}
@Override
public void log(int level, BytePointer message) {
log(level, message.getString());
}
}Configure logging levels through environment variables or programmatically.
Usage Examples:
// Check environment variable configuration
// Set environment variable: LIBFREENECT2_LOGGER_LEVEL=debug
int envLevel = Logger.getDefaultLevel();
switch (envLevel) {
case Logger.None:
System.out.println("Logging disabled");
break;
case Logger.Error:
System.out.println("Error logging only");
break;
case Logger.Warning:
System.out.println("Warning and error logging");
break;
case Logger.Info:
System.out.println("Info, warning, and error logging");
break;
case Logger.Debug:
System.out.println("All logging enabled");
break;
}
// Create loggers with different levels
Logger errorLogger = new FormattedConsoleLogger(Logger.Error);
Logger debugLogger = new FormattedConsoleLogger(Logger.Debug);
// Level names for display
for (int level = Logger.None; level <= Logger.Debug; level++) {
System.out.println("Level " + level + ": " + Logger.level2str(level).getString());
}Implement loggers that output to multiple destinations simultaneously.
Usage Examples:
// Multi-output logger that logs to both console and file
class MultiLogger extends Logger {
private final List<Logger> loggers;
private final int logLevel;
public MultiLogger(int level, Logger... loggers) {
this.logLevel = level;
this.loggers = Arrays.asList(loggers);
}
@Override
public int level() {
return logLevel;
}
@Override
public void log(int level, String message) {
if (level <= this.logLevel) {
for (Logger logger : loggers) {
if (level <= logger.level()) {
logger.log(level, message);
}
}
}
}
@Override
public void log(int level, BytePointer message) {
log(level, message.getString());
}
}
// Usage
try {
FileLogger fileLogger = new FileLogger(Logger.Debug, "libfreenect2.log");
FormattedConsoleLogger consoleLogger = new FormattedConsoleLogger(Logger.Info);
MultiLogger multiLogger = new MultiLogger(Logger.Debug, fileLogger, consoleLogger);
// This would be set as the global logger if the library supported it
// In practice, libfreenect2 manages its own logging internally
} catch (IOException e) {
System.err.println("Failed to create file logger: " + e.getMessage());
}Implement advanced logging features like filtering and conditional output.
Usage Examples:
// Filtered logger that only logs messages containing specific keywords
class FilteredLogger extends Logger {
private final Logger delegate;
private final Set<String> keywords;
private final boolean includeMode; // true = include, false = exclude
public FilteredLogger(Logger delegate, boolean includeMode, String... keywords) {
this.delegate = delegate;
this.includeMode = includeMode;
this.keywords = new HashSet<>(Arrays.asList(keywords));
}
@Override
public int level() {
return delegate.level();
}
@Override
public void log(int level, String message) {
boolean hasKeyword = keywords.stream().anyMatch(message::contains);
if ((includeMode && hasKeyword) || (!includeMode && !hasKeyword)) {
delegate.log(level, message);
}
}
@Override
public void log(int level, BytePointer message) {
log(level, message.getString());
}
}
// Rate-limited logger to prevent spam
class RateLimitedLogger extends Logger {
private final Logger delegate;
private final Map<String, Long> lastLogTime = new HashMap<>();
private final long minIntervalMs;
public RateLimitedLogger(Logger delegate, long minIntervalMs) {
this.delegate = delegate;
this.minIntervalMs = minIntervalMs;
}
@Override
public int level() {
return delegate.level();
}
@Override
public void log(int level, String message) {
long now = System.currentTimeMillis();
Long lastTime = lastLogTime.get(message);
if (lastTime == null || (now - lastTime) >= minIntervalMs) {
delegate.log(level, message);
lastLogTime.put(message, now);
}
}
@Override
public void log(int level, BytePointer message) {
log(level, message.getString());
}
}
// Usage examples
FormattedConsoleLogger baseLogger = new FormattedConsoleLogger(Logger.Debug);
// Only log messages containing "device" or "frame"
FilteredLogger deviceLogger = new FilteredLogger(baseLogger, true, "device", "frame");
// Prevent duplicate messages within 5 seconds
RateLimitedLogger rateLimitedLogger = new RateLimitedLogger(baseLogger, 5000);The library provides global functions for logger management, though these are typically handled internally:
// Note: These are conceptual - actual global logger management
// is handled internally by the native library
/**
* Allocate a Logger instance that outputs log to standard input/output
*/
// Logger createConsoleLogger(int level);
/**
* Create console logger with default level from environment
*/
// Logger createConsoleLoggerWithDefaultLevel();
/**
* Get the pointer to the current logger (informational only)
*/
// Logger getGlobalLogger();
/**
* Set the logger for all log output in this library
* @param logger Pointer to your logger, or null to disable logging
*/
// void setGlobalLogger(Logger logger);public class LibFreenect2Logger {
private static Logger applicationLogger;
public static void initializeLogging(String logFile, int level) {
try {
if (logFile != null) {
FileLogger fileLogger = new FileLogger(level, logFile);
FormattedConsoleLogger consoleLogger = new FormattedConsoleLogger(Logger.Warning);
applicationLogger = new MultiLogger(level, fileLogger, consoleLogger);
} else {
applicationLogger = new FormattedConsoleLogger(level);
}
System.out.println("Logging initialized at level: " +
Logger.level2str(level).getString());
} catch (IOException e) {
System.err.println("Failed to initialize file logging: " + e.getMessage());
applicationLogger = new FormattedConsoleLogger(level);
}
}
public static void logDeviceInfo(Freenect2Device device) {
if (applicationLogger != null && applicationLogger.level() >= Logger.Info) {
String info = "Device Info - Serial: " + device.getSerialNumber().getString() +
", Firmware: " + device.getFirmwareVersion().getString();
applicationLogger.log(Logger.Info, info);
}
}
public static void logError(String message, Exception e) {
if (applicationLogger != null) {
applicationLogger.log(Logger.Error, message + ": " + e.getMessage());
}
}
}Install with Tessl CLI
npx tessl i tessl/maven-org-bytedeco--libfreenect2