Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New Java LoggerFromOptions Logger implementation #13003

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions java/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ set(JNI_NATIVE_SOURCES
rocksjni/jni_perf_context.cc
rocksjni/jnicallback.cc
rocksjni/loggerjnicallback.cc
rocksjni/logger_from_options.cc
rocksjni/lru_cache.cc
rocksjni/memory_util.cc
rocksjni/memtablejni.cc
Expand Down Expand Up @@ -298,6 +299,7 @@ set(JAVA_MAIN_CLASSES
src/main/java/org/rocksdb/util/BytewiseComparator.java
src/main/java/org/rocksdb/util/Environment.java
src/main/java/org/rocksdb/util/IntComparator.java
src/main/java/org/rocksdb/util/LoggerFromOptions.java
src/main/java/org/rocksdb/util/ReverseBytewiseComparator.java
src/main/java/org/rocksdb/util/SizeUnit.java
src/main/java/org/rocksdb/util/StdErrLogger.java
Expand Down
1 change: 1 addition & 0 deletions java/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ NATIVE_JAVA_CLASSES = \
org.rocksdb.WriteBatchWithIndex\
org.rocksdb.WriteBufferManager\
org.rocksdb.WBWIRocksIterator\
org.rocksdb.util.LoggerFromOptions \
org.rocksdb.util.StdErrLogger

NATIVE_JAVA_TEST_CLASSES = \
Expand Down
94 changes: 94 additions & 0 deletions java/rocksjni/logger_from_options.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
// Copyright (c) Meta Platforms, Inc. and affiliates.
//
// This source code is licensed under both the GPLv2 (found in the
// COPYING file in the root directory) and Apache 2.0 License
// (found in the LICENSE.Apache file in the root directory).

#include <jni.h>

#include <memory>

#include "include/org_rocksdb_util_LoggerFromOptions.h"
#include "rocksjni/cplusplus_to_java_convert.h"
#include "rocksjni/portal.h"
#include "util/stderr_logger.h"

/*
* Create an "independent" logger, such as might be supplied to a readonly DB
* (e.g. in a readonly filesystem)
*
* Class: org_rocksdb_util_LoggerFromOptions
* Method: newLoggerFromOptions
* Signature: (J)J
*/
jlong Java_org_rocksdb_util_LoggerFromOptions_createLoggerFromOptions(
JNIEnv* env, jclass, jstring jdb_name, jlong joptions_handle) {
auto* db_options =
reinterpret_cast<ROCKSDB_NAMESPACE::DBOptions*>(joptions_handle);

if (jdb_name == nullptr) {
ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(
env,
ROCKSDB_NAMESPACE::Status::InvalidArgument("Invalid (null) db name."));
return 0;
}
jboolean has_exception = JNI_FALSE;
auto db_name = ROCKSDB_NAMESPACE::JniUtil::copyStdString(
env, jdb_name, &has_exception); // also releases jlog_prefix
if (has_exception == JNI_TRUE) {
return 0;
}

std::shared_ptr<ROCKSDB_NAMESPACE::Logger> logger;

ROCKSDB_NAMESPACE::Status s =
ROCKSDB_NAMESPACE::CreateLoggerFromOptions(db_name, *db_options, &logger);
if (!s.ok()) {
ROCKSDB_NAMESPACE::RocksDBExceptionJni::ThrowNew(env, s);
return 0;
}

return GET_CPLUSPLUS_POINTER(
new std::shared_ptr<ROCKSDB_NAMESPACE::Logger>(std::move(logger)));
}

/*
* Class: org_rocksdb_util_LoggerFromOptions
* Method: setInfoLogLevel
* Signature: (JB)V
*/
void Java_org_rocksdb_util_LoggerFromOptions_setInfoLogLevel(JNIEnv* /*env*/,
jclass /*jcls*/,
jlong jhandle,
jbyte jlog_level) {
auto* handle =
reinterpret_cast<std::shared_ptr<ROCKSDB_NAMESPACE::Logger>*>(jhandle);
handle->get()->SetInfoLogLevel(
static_cast<ROCKSDB_NAMESPACE::InfoLogLevel>(jlog_level));
}

/*
* Class: org_rocksdb_util_LoggerFromOptions
* Method: infoLogLevel
* Signature: (J)B
*/
jbyte Java_org_rocksdb_util_LoggerFromOptions_infoLogLevel(JNIEnv* /*env*/,
jclass /*jcls*/,
jlong jhandle) {
auto* handle =
reinterpret_cast<std::shared_ptr<ROCKSDB_NAMESPACE::Logger>*>(jhandle);
return static_cast<jbyte>(handle->get()->GetInfoLogLevel());
}

/*
* Class: org_rocksdb_util_StdErrLogger
* Method: disposeInternal
* Signature: (J)V
*/
void Java_org_rocksdb_util_StdErrLogger_disposeInternal(JNIEnv* /*env*/,
jobject /*jobj*/,
jlong jhandle) {
auto* handle =
reinterpret_cast<std::shared_ptr<ROCKSDB_NAMESPACE::Logger>*>(jhandle);
delete handle; // delete std::shared_ptr
}
6 changes: 6 additions & 0 deletions java/rocksjni/options.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1101,6 +1101,12 @@ void Java_org_rocksdb_Options_setLogger(JNIEnv* env, jclass, jlong jhandle,
*(reinterpret_cast<std::shared_ptr<ROCKSDB_NAMESPACE::StderrLogger>*>(
jlogger_handle));
break;
case 0x3:
// LOGGER_FROM_OPTIONS_IMPLEMENTATION is a logger created by RocksDB
options->info_log =
*(reinterpret_cast<std::shared_ptr<ROCKSDB_NAMESPACE::Logger>*>(
jlogger_handle));
break;
default:
ROCKSDB_NAMESPACE::IllegalArgumentExceptionJni::ThrowNew(
env, ROCKSDB_NAMESPACE::Status::InvalidArgument(
Expand Down
3 changes: 2 additions & 1 deletion java/src/main/java/org/rocksdb/LoggerType.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
*/
public enum LoggerType {
JAVA_IMPLEMENTATION((byte) 0x1),
STDERR_IMPLEMENTATION((byte) 0x2);
STDERR_IMPLEMENTATION((byte) 0x2),
FROM_OPTIONS_IMPLEMENTATION((byte) 0x3);

private final byte value;

Expand Down
46 changes: 46 additions & 0 deletions java/src/main/java/org/rocksdb/util/LoggerFromOptions.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Copyright (c) Meta Platforms, Inc. and affiliates.
//
// This source code is licensed under both the GPLv2 (found in the
// COPYING file in the root directory) and Apache 2.0 License
// (found in the LICENSE.Apache file in the root directory).

package org.rocksdb.util;

import org.rocksdb.*;

/**
* This is a Java wrapper around a native RocksDB logger created by the
* CreateLoggerFromOptions API.
*/
public class LoggerFromOptions extends RocksObject implements LoggerInterface {
private LoggerFromOptions(final String dbName, final DBOptions dbOptions) {
super(createLoggerFromOptions(dbName, dbOptions.getNativeHandle()));
}

static public LoggerFromOptions CreateLoggerFromOptions(
final String dbName, final DBOptions dbOptions) {
return new LoggerFromOptions(dbName, dbOptions);
}

@Override
public void setInfoLogLevel(InfoLogLevel logLevel) {
setInfoLogLevel(nativeHandle_, logLevel.getValue());
}

@Override
public InfoLogLevel infoLogLevel() {
return InfoLogLevel.getInfoLogLevel(infoLogLevel(nativeHandle_));
}

@Override
public LoggerType getLoggerType() {
return LoggerType.FROM_OPTIONS_IMPLEMENTATION;
}

@Override protected native void disposeInternal(long handle);

private static native long createLoggerFromOptions(final String dbName, final long dbOptions);

private static native void setInfoLogLevel(final long handle, final byte logLevel);
private static native byte infoLogLevel(final long handle);
}
71 changes: 71 additions & 0 deletions java/src/test/java/org/rocksdb/util/LoggerFromOptionsTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// Copyright (c) Meta Platforms, Inc. and affiliates.
//
// This source code is licensed under both the GPLv2 (found in the
// COPYING file in the root directory) and Apache 2.0 License
// (found in the LICENSE.Apache file in the root directory).

package org.rocksdb.util;

import static org.assertj.core.api.Assertions.assertThat;

import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.rocksdb.*;

public class LoggerFromOptionsTest {
@ClassRule
public static final RocksNativeLibraryResource ROCKS_NATIVE_LIBRARY_RESOURCE =
new RocksNativeLibraryResource();

@Rule public TemporaryFolder dbFolder = new TemporaryFolder();

// The log is meant to show up in a different directory from the DB..
@Rule public TemporaryFolder logFolder = new TemporaryFolder();

@Test
public void openReadOnlyWithLoggerFromOptions() throws RocksDBException, IOException {
// Create the DB and close it again
try (final Options options = new Options().setCreateIfMissing(true);
final FlushOptions flushOptions = new FlushOptions().setWaitForFlush(true);
final RocksDB db = RocksDB.open(options, dbFolder.getRoot().getAbsolutePath())) {
db.flush(flushOptions);
}

LoggerFromOptions logger =
LoggerFromOptions.CreateLoggerFromOptions(logFolder.getRoot().toString(), new DBOptions());
logger.setInfoLogLevel(InfoLogLevel.DEBUG_LEVEL);

// Expect these configured options to be output in the log
List<String> remainingMatches = new ArrayList<>(
Arrays.asList("Options.max_log_file_size: 65536", "Options.log_file_time_to_roll: 2048",
"Options.keep_log_file_num: 8", "Options.recycle_log_file_num: 3"));

// Configure the log in order for the dump of log configuration to the log to be unique
// Open the DB readonly and give it the new logger to use
try (final Options options = new Options()
.setInfoLogLevel(InfoLogLevel.DEBUG_LEVEL)
.setLogger(logger)
.setMaxLogFileSize(1024L * 64L)
.setRecycleLogFileNum(3)
.setLogFileTimeToRoll(2048)
.setKeepLogFileNum(8);
final RocksDB db = RocksDB.openReadOnly(options, dbFolder.getRoot().getAbsolutePath())) {
assertThat(db.getDBOptions()).isNotNull();
}

// Look for evidence that the (readonly) DB has written to the logger we gave it
File[] logFiles = Objects.requireNonNull(logFolder.getRoot().listFiles());
assertThat(logFiles.length).isEqualTo(1);
File logFile = logFiles[0];
BufferedReader reader = new BufferedReader(new FileReader(logFile));
reader.lines().forEach(s -> remainingMatches.removeIf(s::contains));
assertThat(remainingMatches).as("Not all expected options have been observed in log").isEmpty();
}
}
1 change: 1 addition & 0 deletions src.mk
Original file line number Diff line number Diff line change
Expand Up @@ -689,6 +689,7 @@ JNI_NATIVE_SOURCES = \
java/rocksjni/jni_multiget_helpers.cc \
java/rocksjni/jnicallback.cc \
java/rocksjni/loggerjnicallback.cc \
java/rocksjni/logger_from_options.cc \
java/rocksjni/lru_cache.cc \
java/rocksjni/memtablejni.cc \
java/rocksjni/memory_util.cc \
Expand Down
Loading