commit
eafa1bfc3c
@ -0,0 +1,195 @@ |
|||||||
|
// Copyright (c) 2015, Facebook, Inc. All rights reserved.
|
||||||
|
// This source code is licensed under the BSD-style license found in the
|
||||||
|
// LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
// of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
//
|
||||||
|
// This file implements the callback "bridge" between Java and C++ for
|
||||||
|
// rocksdb::Logger.
|
||||||
|
|
||||||
|
#include "include/org_rocksdb_Logger.h" |
||||||
|
|
||||||
|
#include "rocksjni/loggerjnicallback.h" |
||||||
|
#include "rocksjni/portal.h" |
||||||
|
|
||||||
|
namespace rocksdb { |
||||||
|
|
||||||
|
LoggerJniCallback::LoggerJniCallback( |
||||||
|
JNIEnv* env, jobject jlogger) { |
||||||
|
|
||||||
|
const jint rs = env->GetJavaVM(&m_jvm); |
||||||
|
assert(rs == JNI_OK); |
||||||
|
|
||||||
|
// Note: we want to access the Java Logger instance
|
||||||
|
// across multiple method calls, so we create a global ref
|
||||||
|
m_jLogger = env->NewGlobalRef(jlogger); |
||||||
|
m_jLogMethodId = LoggerJni::getLogMethodId(env); |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* Get JNIEnv for current native thread |
||||||
|
*/ |
||||||
|
JNIEnv* LoggerJniCallback::getJniEnv() const { |
||||||
|
JNIEnv *env; |
||||||
|
jint rs = m_jvm->AttachCurrentThread(reinterpret_cast<void **>(&env), NULL); |
||||||
|
assert(rs == JNI_OK); |
||||||
|
return env; |
||||||
|
} |
||||||
|
|
||||||
|
void LoggerJniCallback::Logv(const char* format, va_list ap) { |
||||||
|
// We implement this method because it is virtual but we don't
|
||||||
|
// use it because we need to know about the log level.
|
||||||
|
} |
||||||
|
|
||||||
|
void LoggerJniCallback::Logv(const InfoLogLevel log_level, |
||||||
|
const char* format, va_list ap) { |
||||||
|
if (GetInfoLogLevel() <= log_level) { |
||||||
|
JNIEnv* env = getJniEnv(); |
||||||
|
|
||||||
|
// determine InfoLogLevel java enum instance
|
||||||
|
jobject jlog_level; |
||||||
|
switch (log_level) { |
||||||
|
case rocksdb::InfoLogLevel::DEBUG_LEVEL: |
||||||
|
jlog_level = InfoLogLevelJni::DEBUG_LEVEL(env); |
||||||
|
break; |
||||||
|
case rocksdb::InfoLogLevel::INFO_LEVEL: |
||||||
|
jlog_level = InfoLogLevelJni::INFO_LEVEL(env); |
||||||
|
break; |
||||||
|
case rocksdb::InfoLogLevel::ERROR_LEVEL: |
||||||
|
jlog_level = InfoLogLevelJni::ERROR_LEVEL(env); |
||||||
|
break; |
||||||
|
case rocksdb::InfoLogLevel::FATAL_LEVEL: |
||||||
|
jlog_level = InfoLogLevelJni::FATAL_LEVEL(env); |
||||||
|
break; |
||||||
|
default: |
||||||
|
jlog_level = InfoLogLevelJni::FATAL_LEVEL(env); |
||||||
|
break; |
||||||
|
} |
||||||
|
|
||||||
|
// We try twice: the first time with a fixed-size stack allocated buffer,
|
||||||
|
// and the second time with a much larger dynamically allocated buffer.
|
||||||
|
char buffer[500]; |
||||||
|
for (int iter = 0; iter < 2; iter++) { |
||||||
|
char* base; |
||||||
|
int bufsize; |
||||||
|
if (iter == 0) { |
||||||
|
bufsize = sizeof(buffer); |
||||||
|
base = buffer; |
||||||
|
} else { |
||||||
|
bufsize = 30000; |
||||||
|
base = new char[bufsize]; |
||||||
|
} |
||||||
|
char* p = base; |
||||||
|
char* limit = base + bufsize; |
||||||
|
// Print the message
|
||||||
|
if (p < limit) { |
||||||
|
va_list backup_ap; |
||||||
|
va_copy(backup_ap, ap); |
||||||
|
p += vsnprintf(p, limit - p, format, backup_ap); |
||||||
|
va_end(backup_ap); |
||||||
|
} |
||||||
|
// Truncate to available space if necessary
|
||||||
|
if (p >= limit) { |
||||||
|
if (iter == 0) { |
||||||
|
continue; // Try again with larger buffer
|
||||||
|
} else { |
||||||
|
p = limit - 1; |
||||||
|
} |
||||||
|
} |
||||||
|
assert(p < limit); |
||||||
|
*p++ = '\0'; |
||||||
|
|
||||||
|
// pass java string to callback handler
|
||||||
|
env->CallVoidMethod( |
||||||
|
m_jLogger, |
||||||
|
m_jLogMethodId, |
||||||
|
jlog_level, |
||||||
|
env->NewStringUTF(base)); |
||||||
|
|
||||||
|
if (base != buffer) { |
||||||
|
delete[] base; |
||||||
|
} |
||||||
|
break; |
||||||
|
} |
||||||
|
m_jvm->DetachCurrentThread(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
LoggerJniCallback::~LoggerJniCallback() { |
||||||
|
JNIEnv* env = getJniEnv(); |
||||||
|
env->DeleteGlobalRef(m_jLogger); |
||||||
|
m_jvm->DetachCurrentThread(); |
||||||
|
} |
||||||
|
|
||||||
|
} // namespace rocksdb
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class: org_rocksdb_Logger |
||||||
|
* Method: createNewLoggerOptions |
||||||
|
* Signature: (J)V |
||||||
|
*/ |
||||||
|
void Java_org_rocksdb_Logger_createNewLoggerOptions( |
||||||
|
JNIEnv* env, jobject jobj, jlong joptions) { |
||||||
|
rocksdb::LoggerJniCallback* c = |
||||||
|
new rocksdb::LoggerJniCallback(env, jobj); |
||||||
|
// set log level
|
||||||
|
c->SetInfoLogLevel(reinterpret_cast<rocksdb::Options*> |
||||||
|
(joptions)->info_log_level); |
||||||
|
std::shared_ptr<rocksdb::LoggerJniCallback> *pLoggerJniCallback = |
||||||
|
new std::shared_ptr<rocksdb::LoggerJniCallback>; |
||||||
|
*pLoggerJniCallback = std::shared_ptr<rocksdb::LoggerJniCallback>(c); |
||||||
|
rocksdb::LoggerJni::setHandle(env, jobj, pLoggerJniCallback); |
||||||
|
} |
||||||
|
|
||||||
|
/*
|
||||||
|
* Class: org_rocksdb_Logger |
||||||
|
* Method: createNewLoggerDbOptions |
||||||
|
* Signature: (J)V |
||||||
|
*/ |
||||||
|
void Java_org_rocksdb_Logger_createNewLoggerDbOptions( |
||||||
|
JNIEnv* env, jobject jobj, jlong jdb_options) { |
||||||
|
rocksdb::LoggerJniCallback* c = |
||||||
|
new rocksdb::LoggerJniCallback(env, jobj); |
||||||
|
// set log level
|
||||||
|
c->SetInfoLogLevel(reinterpret_cast<rocksdb::DBOptions*> |
||||||
|
(jdb_options)->info_log_level); |
||||||
|
std::shared_ptr<rocksdb::LoggerJniCallback> *pLoggerJniCallback = |
||||||
|
new std::shared_ptr<rocksdb::LoggerJniCallback>; |
||||||
|
*pLoggerJniCallback = std::shared_ptr<rocksdb::LoggerJniCallback>(c); |
||||||
|
rocksdb::LoggerJni::setHandle(env, jobj, pLoggerJniCallback); |
||||||
|
} |
||||||
|
|
||||||
|
/*
|
||||||
|
* Class: org_rocksdb_Logger |
||||||
|
* Method: setInfoLogLevel |
||||||
|
* Signature: (JB)V |
||||||
|
*/ |
||||||
|
void Java_org_rocksdb_Logger_setInfoLogLevel( |
||||||
|
JNIEnv* env, jobject jobj, jlong jhandle, jbyte jlog_level) { |
||||||
|
std::shared_ptr<rocksdb::LoggerJniCallback> *handle = |
||||||
|
reinterpret_cast<std::shared_ptr<rocksdb::LoggerJniCallback> *>(jhandle); |
||||||
|
(*handle)->SetInfoLogLevel(static_cast<rocksdb::InfoLogLevel>(jlog_level)); |
||||||
|
} |
||||||
|
|
||||||
|
/*
|
||||||
|
* Class: org_rocksdb_Logger |
||||||
|
* Method: infoLogLevel |
||||||
|
* Signature: (J)B |
||||||
|
*/ |
||||||
|
jbyte Java_org_rocksdb_Logger_infoLogLevel( |
||||||
|
JNIEnv* env, jobject jobj, jlong jhandle) { |
||||||
|
std::shared_ptr<rocksdb::LoggerJniCallback> *handle = |
||||||
|
reinterpret_cast<std::shared_ptr<rocksdb::LoggerJniCallback> *>(jhandle); |
||||||
|
return static_cast<jbyte>((*handle)->GetInfoLogLevel()); |
||||||
|
} |
||||||
|
|
||||||
|
/*
|
||||||
|
* Class: org_rocksdb_Logger |
||||||
|
* Method: disposeInternal |
||||||
|
* Signature: (J)V |
||||||
|
*/ |
||||||
|
void Java_org_rocksdb_Logger_disposeInternal( |
||||||
|
JNIEnv* env, jobject jobj, jlong jhandle) { |
||||||
|
std::shared_ptr<rocksdb::LoggerJniCallback> *handle = |
||||||
|
reinterpret_cast<std::shared_ptr<rocksdb::LoggerJniCallback> *>(jhandle); |
||||||
|
handle->reset(); |
||||||
|
} |
@ -0,0 +1,44 @@ |
|||||||
|
// Copyright (c) 2015, Facebook, Inc. All rights reserved.
|
||||||
|
// This source code is licensed under the BSD-style license found in the
|
||||||
|
// LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
// of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
//
|
||||||
|
// This file implements the callback "bridge" between Java and C++ for
|
||||||
|
// rocksdb::Logger
|
||||||
|
|
||||||
|
#ifndef JAVA_ROCKSJNI_LOGGERJNICALLBACK_H_ |
||||||
|
#define JAVA_ROCKSJNI_LOGGERJNICALLBACK_H_ |
||||||
|
|
||||||
|
#include <jni.h> |
||||||
|
#include <string> |
||||||
|
#include "port/port.h" |
||||||
|
#include "rocksdb/env.h" |
||||||
|
|
||||||
|
namespace rocksdb { |
||||||
|
|
||||||
|
class LoggerJniCallback : public Logger { |
||||||
|
public: |
||||||
|
LoggerJniCallback(JNIEnv* env, jobject jLogger); |
||||||
|
virtual ~LoggerJniCallback(); |
||||||
|
|
||||||
|
using Logger::SetInfoLogLevel; |
||||||
|
using Logger::GetInfoLogLevel; |
||||||
|
// Write an entry to the log file with the specified format.
|
||||||
|
virtual void Logv(const char* format, va_list ap); |
||||||
|
// Write an entry to the log file with the specified log level
|
||||||
|
// and format. Any log with level under the internal log level
|
||||||
|
// of *this (see @SetInfoLogLevel and @GetInfoLogLevel) will not be
|
||||||
|
// printed.
|
||||||
|
virtual void Logv(const InfoLogLevel log_level, |
||||||
|
const char* format, va_list ap); |
||||||
|
|
||||||
|
protected: |
||||||
|
JNIEnv* getJniEnv() const; |
||||||
|
private: |
||||||
|
JavaVM* m_jvm; |
||||||
|
jobject m_jLogger; |
||||||
|
jmethodID m_jLogMethodId; |
||||||
|
}; |
||||||
|
} // namespace rocksdb
|
||||||
|
|
||||||
|
#endif // JAVA_ROCKSJNI_LOGGERJNICALLBACK_H_
|
@ -0,0 +1,87 @@ |
|||||||
|
// Copyright (c) 2015, Facebook, Inc. All rights reserved.
|
||||||
|
// This source code is licensed under the BSD-style license found in the
|
||||||
|
// LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
// of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
|
||||||
|
package org.rocksdb; |
||||||
|
|
||||||
|
/** |
||||||
|
* <p>This class provides a custom logger functionality |
||||||
|
* in Java which wraps {@code RocksDB} logging facilities. |
||||||
|
* </p> |
||||||
|
* |
||||||
|
* <p>Using this class RocksDB can log with common |
||||||
|
* Java logging APIs like Log4j or Slf4j without keeping |
||||||
|
* database logs in the filesystem.</p> |
||||||
|
*/ |
||||||
|
public abstract class Logger extends RocksObject { |
||||||
|
|
||||||
|
/** |
||||||
|
* <p>AbstractLogger constructor.</p> |
||||||
|
* |
||||||
|
* <p><strong>Important:</strong> the log level set within |
||||||
|
* the {@link org.rocksdb.Options} instance will be used as |
||||||
|
* maximum log level of RocksDB.</p> |
||||||
|
* |
||||||
|
* @param options {@link org.rocksdb.Options} instance. |
||||||
|
*/ |
||||||
|
public Logger(final Options options) { |
||||||
|
createNewLoggerOptions(options.nativeHandle_); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* <p>AbstractLogger constructor.</p> |
||||||
|
* |
||||||
|
* <p><strong>Important:</strong> the log level set within |
||||||
|
* the {@link org.rocksdb.DBOptions} instance will be used |
||||||
|
* as maximum log level of RocksDB.</p> |
||||||
|
* |
||||||
|
* @param dboptions {@link org.rocksdb.DBOptions} instance. |
||||||
|
*/ |
||||||
|
public Logger(final DBOptions dboptions) { |
||||||
|
createNewLoggerDbOptions(dboptions.nativeHandle_); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Set {@link org.rocksdb.InfoLogLevel} to AbstractLogger. |
||||||
|
* |
||||||
|
* @param infoLogLevel {@link org.rocksdb.InfoLogLevel} instance. |
||||||
|
*/ |
||||||
|
public void setInfoLogLevel(final InfoLogLevel infoLogLevel) { |
||||||
|
setInfoLogLevel(nativeHandle_, infoLogLevel.getValue()); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Return the loggers log level. |
||||||
|
* |
||||||
|
* @return {@link org.rocksdb.InfoLogLevel} instance. |
||||||
|
*/ |
||||||
|
public InfoLogLevel infoLogLevel() { |
||||||
|
return InfoLogLevel.getInfoLogLevel( |
||||||
|
infoLogLevel(nativeHandle_)); |
||||||
|
} |
||||||
|
|
||||||
|
protected abstract void log(InfoLogLevel infoLogLevel, |
||||||
|
String logMsg); |
||||||
|
|
||||||
|
/** |
||||||
|
* Deletes underlying C++ slice pointer. |
||||||
|
* Note that this function should be called only after all |
||||||
|
* RocksDB instances referencing the slice are closed. |
||||||
|
* Otherwise an undefined behavior will occur. |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
protected void disposeInternal() { |
||||||
|
assert(isInitialized()); |
||||||
|
disposeInternal(nativeHandle_); |
||||||
|
} |
||||||
|
|
||||||
|
protected native void createNewLoggerOptions( |
||||||
|
long options); |
||||||
|
protected native void createNewLoggerDbOptions( |
||||||
|
long dbOptions); |
||||||
|
protected native void setInfoLogLevel(long handle, |
||||||
|
byte infoLogLevel); |
||||||
|
protected native byte infoLogLevel(long handle); |
||||||
|
private native void disposeInternal(long handle); |
||||||
|
} |
@ -0,0 +1,220 @@ |
|||||||
|
package org.rocksdb; |
||||||
|
|
||||||
|
import org.junit.ClassRule; |
||||||
|
import org.junit.Rule; |
||||||
|
import org.junit.Test; |
||||||
|
import org.junit.rules.TemporaryFolder; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
import java.util.concurrent.atomic.AtomicInteger; |
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat; |
||||||
|
|
||||||
|
public class LoggerTest { |
||||||
|
@ClassRule |
||||||
|
public static final RocksMemoryResource rocksMemoryResource = |
||||||
|
new RocksMemoryResource(); |
||||||
|
|
||||||
|
@Rule |
||||||
|
public TemporaryFolder dbFolder = new TemporaryFolder(); |
||||||
|
|
||||||
|
private AtomicInteger logMessageCounter = new AtomicInteger(); |
||||||
|
|
||||||
|
@Test |
||||||
|
public void customLogger() throws RocksDBException { |
||||||
|
RocksDB db = null; |
||||||
|
logMessageCounter.set(0); |
||||||
|
try { |
||||||
|
|
||||||
|
// Setup options
|
||||||
|
final Options options = new Options(). |
||||||
|
setInfoLogLevel(InfoLogLevel.DEBUG_LEVEL). |
||||||
|
setCreateIfMissing(true); |
||||||
|
|
||||||
|
// Create new logger with max log level passed by options
|
||||||
|
Logger logger = new Logger(options) { |
||||||
|
@Override |
||||||
|
protected void log(InfoLogLevel infoLogLevel, String logMsg) { |
||||||
|
assertThat(logMsg).isNotNull(); |
||||||
|
assertThat(logMsg.length()).isGreaterThan(0); |
||||||
|
logMessageCounter.incrementAndGet(); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
// Set custom logger to options
|
||||||
|
options.setLogger(logger); |
||||||
|
|
||||||
|
db = RocksDB.open(options, dbFolder.getRoot().getAbsolutePath()); |
||||||
|
|
||||||
|
// there should be more than zero received log messages in
|
||||||
|
// debug level.
|
||||||
|
assertThat(logMessageCounter.get()).isGreaterThan(0); |
||||||
|
} finally { |
||||||
|
if (db != null) { |
||||||
|
db.close(); |
||||||
|
} |
||||||
|
} |
||||||
|
logMessageCounter.set(0); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Test |
||||||
|
public void fatalLogger() throws RocksDBException { |
||||||
|
RocksDB db = null; |
||||||
|
logMessageCounter.set(0); |
||||||
|
|
||||||
|
try { |
||||||
|
// Setup options
|
||||||
|
final Options options = new Options(). |
||||||
|
setInfoLogLevel(InfoLogLevel.FATAL_LEVEL). |
||||||
|
setCreateIfMissing(true); |
||||||
|
|
||||||
|
// Create new logger with max log level passed by options
|
||||||
|
Logger logger = new Logger(options) { |
||||||
|
@Override |
||||||
|
protected void log(InfoLogLevel infoLogLevel, String logMsg) { |
||||||
|
assertThat(logMsg).isNotNull(); |
||||||
|
assertThat(logMsg.length()).isGreaterThan(0); |
||||||
|
logMessageCounter.incrementAndGet(); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
// Set custom logger to options
|
||||||
|
options.setLogger(logger); |
||||||
|
|
||||||
|
db = RocksDB.open(options, dbFolder.getRoot().getAbsolutePath()); |
||||||
|
|
||||||
|
// there should be zero messages
|
||||||
|
// using fatal level as log level.
|
||||||
|
assertThat(logMessageCounter.get()).isEqualTo(0); |
||||||
|
} finally { |
||||||
|
if (db != null) { |
||||||
|
db.close(); |
||||||
|
} |
||||||
|
} |
||||||
|
logMessageCounter.set(0); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void dbOptionsLogger() throws RocksDBException { |
||||||
|
RocksDB db = null; |
||||||
|
Logger logger = null; |
||||||
|
List<ColumnFamilyHandle> cfHandles = new ArrayList<>(); |
||||||
|
List<ColumnFamilyDescriptor> cfDescriptors = new ArrayList<>(); |
||||||
|
cfDescriptors.add(new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY)); |
||||||
|
|
||||||
|
logMessageCounter.set(0); |
||||||
|
try { |
||||||
|
// Setup options
|
||||||
|
final DBOptions options = new DBOptions(). |
||||||
|
setInfoLogLevel(InfoLogLevel.FATAL_LEVEL). |
||||||
|
setCreateIfMissing(true); |
||||||
|
|
||||||
|
// Create new logger with max log level passed by options
|
||||||
|
logger = new Logger(options) { |
||||||
|
@Override |
||||||
|
protected void log(InfoLogLevel infoLogLevel, String logMsg) { |
||||||
|
assertThat(logMsg).isNotNull(); |
||||||
|
assertThat(logMsg.length()).isGreaterThan(0); |
||||||
|
logMessageCounter.incrementAndGet(); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
// Set custom logger to options
|
||||||
|
options.setLogger(logger); |
||||||
|
db = RocksDB.open(options, dbFolder.getRoot().getAbsolutePath(), |
||||||
|
cfDescriptors, cfHandles); |
||||||
|
// there should be zero messages
|
||||||
|
// using fatal level as log level.
|
||||||
|
assertThat(logMessageCounter.get()).isEqualTo(0); |
||||||
|
logMessageCounter.set(0); |
||||||
|
} finally { |
||||||
|
for (ColumnFamilyHandle columnFamilyHandle : cfHandles) { |
||||||
|
columnFamilyHandle.dispose(); |
||||||
|
} |
||||||
|
if (db != null) { |
||||||
|
db.close(); |
||||||
|
} |
||||||
|
if (logger != null) { |
||||||
|
logger.dispose(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void setInfoLogLevel() { |
||||||
|
Logger logger = null; |
||||||
|
try { |
||||||
|
// Setup options
|
||||||
|
final Options options = new Options(). |
||||||
|
setInfoLogLevel(InfoLogLevel.FATAL_LEVEL). |
||||||
|
setCreateIfMissing(true); |
||||||
|
|
||||||
|
// Create new logger with max log level passed by options
|
||||||
|
logger = new Logger(options) { |
||||||
|
@Override |
||||||
|
protected void log(InfoLogLevel infoLogLevel, String logMsg) { |
||||||
|
assertThat(logMsg).isNotNull(); |
||||||
|
assertThat(logMsg.length()).isGreaterThan(0); |
||||||
|
logMessageCounter.incrementAndGet(); |
||||||
|
} |
||||||
|
}; |
||||||
|
assertThat(logger.infoLogLevel()). |
||||||
|
isEqualTo(InfoLogLevel.FATAL_LEVEL); |
||||||
|
logger.setInfoLogLevel(InfoLogLevel.DEBUG_LEVEL); |
||||||
|
assertThat(logger.infoLogLevel()). |
||||||
|
isEqualTo(InfoLogLevel.DEBUG_LEVEL); |
||||||
|
} finally { |
||||||
|
if (logger != null) { |
||||||
|
logger.dispose(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void changeLogLevelAtRuntime() throws RocksDBException { |
||||||
|
RocksDB db = null; |
||||||
|
logMessageCounter.set(0); |
||||||
|
|
||||||
|
try { |
||||||
|
// Setup options
|
||||||
|
final Options options = new Options(). |
||||||
|
setInfoLogLevel(InfoLogLevel.FATAL_LEVEL). |
||||||
|
setCreateIfMissing(true); |
||||||
|
|
||||||
|
// Create new logger with max log level passed by options
|
||||||
|
Logger logger = new Logger(options) { |
||||||
|
@Override |
||||||
|
protected void log(InfoLogLevel infoLogLevel, String logMsg) { |
||||||
|
assertThat(logMsg).isNotNull(); |
||||||
|
assertThat(logMsg.length()).isGreaterThan(0); |
||||||
|
logMessageCounter.incrementAndGet(); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
// Set custom logger to options
|
||||||
|
options.setLogger(logger); |
||||||
|
db = RocksDB.open(options, dbFolder.getRoot().getAbsolutePath()); |
||||||
|
|
||||||
|
// there should be zero messages
|
||||||
|
// using fatal level as log level.
|
||||||
|
assertThat(logMessageCounter.get()).isEqualTo(0); |
||||||
|
|
||||||
|
// change log level to debug level
|
||||||
|
logger.setInfoLogLevel(InfoLogLevel.DEBUG_LEVEL); |
||||||
|
|
||||||
|
db.put("key".getBytes(), "value".getBytes()); |
||||||
|
db.flush(new FlushOptions().setWaitForFlush(true)); |
||||||
|
|
||||||
|
// messages shall be received due to previous actions.
|
||||||
|
assertThat(logMessageCounter.get()).isNotEqualTo(0); |
||||||
|
|
||||||
|
} finally { |
||||||
|
if (db != null) { |
||||||
|
db.close(); |
||||||
|
} |
||||||
|
} |
||||||
|
logMessageCounter.set(0); |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue