]>
git.proxmox.com Git - ceph.git/blob - ceph/src/rocksdb/java/rocksjni/loggerjnicallback.cc
1 // Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
2 // This source code is licensed under both the GPLv2 (found in the
3 // COPYING file in the root directory) and Apache 2.0 License
4 // (found in the LICENSE.Apache file in the root directory).
6 // This file implements the callback "bridge" between Java and C++ for
7 // ROCKSDB_NAMESPACE::Logger.
9 #include "rocksjni/loggerjnicallback.h"
14 #include "include/org_rocksdb_Logger.h"
15 #include "rocksjni/cplusplus_to_java_convert.h"
16 #include "rocksjni/portal.h"
18 namespace ROCKSDB_NAMESPACE
{
20 LoggerJniCallback::LoggerJniCallback(JNIEnv
* env
, jobject jlogger
)
21 : JniCallback(env
, jlogger
) {
22 m_jLogMethodId
= LoggerJni::getLogMethodId(env
);
23 if (m_jLogMethodId
== nullptr) {
24 // exception thrown: NoSuchMethodException or OutOfMemoryError
28 jobject jdebug_level
= InfoLogLevelJni::DEBUG_LEVEL(env
);
29 if (jdebug_level
== nullptr) {
30 // exception thrown: NoSuchFieldError, ExceptionInInitializerError
31 // or OutOfMemoryError
34 m_jdebug_level
= env
->NewGlobalRef(jdebug_level
);
35 if (m_jdebug_level
== nullptr) {
36 // exception thrown: OutOfMemoryError
40 jobject jinfo_level
= InfoLogLevelJni::INFO_LEVEL(env
);
41 if (jinfo_level
== nullptr) {
42 // exception thrown: NoSuchFieldError, ExceptionInInitializerError
43 // or OutOfMemoryError
46 m_jinfo_level
= env
->NewGlobalRef(jinfo_level
);
47 if (m_jinfo_level
== nullptr) {
48 // exception thrown: OutOfMemoryError
52 jobject jwarn_level
= InfoLogLevelJni::WARN_LEVEL(env
);
53 if (jwarn_level
== nullptr) {
54 // exception thrown: NoSuchFieldError, ExceptionInInitializerError
55 // or OutOfMemoryError
58 m_jwarn_level
= env
->NewGlobalRef(jwarn_level
);
59 if (m_jwarn_level
== nullptr) {
60 // exception thrown: OutOfMemoryError
64 jobject jerror_level
= InfoLogLevelJni::ERROR_LEVEL(env
);
65 if (jerror_level
== nullptr) {
66 // exception thrown: NoSuchFieldError, ExceptionInInitializerError
67 // or OutOfMemoryError
70 m_jerror_level
= env
->NewGlobalRef(jerror_level
);
71 if (m_jerror_level
== nullptr) {
72 // exception thrown: OutOfMemoryError
76 jobject jfatal_level
= InfoLogLevelJni::FATAL_LEVEL(env
);
77 if (jfatal_level
== nullptr) {
78 // exception thrown: NoSuchFieldError, ExceptionInInitializerError
79 // or OutOfMemoryError
82 m_jfatal_level
= env
->NewGlobalRef(jfatal_level
);
83 if (m_jfatal_level
== nullptr) {
84 // exception thrown: OutOfMemoryError
88 jobject jheader_level
= InfoLogLevelJni::HEADER_LEVEL(env
);
89 if (jheader_level
== nullptr) {
90 // exception thrown: NoSuchFieldError, ExceptionInInitializerError
91 // or OutOfMemoryError
94 m_jheader_level
= env
->NewGlobalRef(jheader_level
);
95 if (m_jheader_level
== nullptr) {
96 // exception thrown: OutOfMemoryError
101 void LoggerJniCallback::Logv(const char* /*format*/, va_list /*ap*/) {
102 // We implement this method because it is virtual but we don't
103 // use it because we need to know about the log level.
106 void LoggerJniCallback::Logv(const InfoLogLevel log_level
, const char* format
,
108 if (GetInfoLogLevel() <= log_level
) {
109 // determine InfoLogLevel java enum instance
112 case ROCKSDB_NAMESPACE::InfoLogLevel::DEBUG_LEVEL
:
113 jlog_level
= m_jdebug_level
;
115 case ROCKSDB_NAMESPACE::InfoLogLevel::INFO_LEVEL
:
116 jlog_level
= m_jinfo_level
;
118 case ROCKSDB_NAMESPACE::InfoLogLevel::WARN_LEVEL
:
119 jlog_level
= m_jwarn_level
;
121 case ROCKSDB_NAMESPACE::InfoLogLevel::ERROR_LEVEL
:
122 jlog_level
= m_jerror_level
;
124 case ROCKSDB_NAMESPACE::InfoLogLevel::FATAL_LEVEL
:
125 jlog_level
= m_jfatal_level
;
127 case ROCKSDB_NAMESPACE::InfoLogLevel::HEADER_LEVEL
:
128 jlog_level
= m_jheader_level
;
131 jlog_level
= m_jfatal_level
;
135 assert(format
!= nullptr);
136 const std::unique_ptr
<char[]> msg
= format_str(format
, ap
);
138 // pass msg to java callback handler
139 jboolean attached_thread
= JNI_FALSE
;
140 JNIEnv
* env
= getJniEnv(&attached_thread
);
141 assert(env
!= nullptr);
143 jstring jmsg
= env
->NewStringUTF(msg
.get());
144 if (jmsg
== nullptr) {
145 // unable to construct string
146 if (env
->ExceptionCheck()) {
147 env
->ExceptionDescribe(); // print out exception to stderr
149 releaseJniEnv(attached_thread
);
152 if (env
->ExceptionCheck()) {
153 // exception thrown: OutOfMemoryError
154 env
->ExceptionDescribe(); // print out exception to stderr
155 env
->DeleteLocalRef(jmsg
);
156 releaseJniEnv(attached_thread
);
160 env
->CallVoidMethod(m_jcallback_obj
, m_jLogMethodId
, jlog_level
, jmsg
);
161 if (env
->ExceptionCheck()) {
163 env
->ExceptionDescribe(); // print out exception to stderr
164 env
->DeleteLocalRef(jmsg
);
165 releaseJniEnv(attached_thread
);
169 env
->DeleteLocalRef(jmsg
);
170 releaseJniEnv(attached_thread
);
174 std::unique_ptr
<char[]> LoggerJniCallback::format_str(const char* format
,
178 va_copy(ap_copy
, ap
);
179 const size_t required
=
180 vsnprintf(nullptr, 0, format
, ap_copy
) + 1; // Extra space for '\0'
183 std::unique_ptr
<char[]> buf(new char[required
]);
185 va_copy(ap_copy
, ap
);
186 vsnprintf(buf
.get(), required
, format
, ap_copy
);
191 LoggerJniCallback::~LoggerJniCallback() {
192 jboolean attached_thread
= JNI_FALSE
;
193 JNIEnv
* env
= getJniEnv(&attached_thread
);
194 assert(env
!= nullptr);
196 if (m_jdebug_level
!= nullptr) {
197 env
->DeleteGlobalRef(m_jdebug_level
);
200 if (m_jinfo_level
!= nullptr) {
201 env
->DeleteGlobalRef(m_jinfo_level
);
204 if (m_jwarn_level
!= nullptr) {
205 env
->DeleteGlobalRef(m_jwarn_level
);
208 if (m_jerror_level
!= nullptr) {
209 env
->DeleteGlobalRef(m_jerror_level
);
212 if (m_jfatal_level
!= nullptr) {
213 env
->DeleteGlobalRef(m_jfatal_level
);
216 if (m_jheader_level
!= nullptr) {
217 env
->DeleteGlobalRef(m_jheader_level
);
220 releaseJniEnv(attached_thread
);
223 } // namespace ROCKSDB_NAMESPACE
226 * Class: org_rocksdb_Logger
227 * Method: createNewLoggerOptions
230 jlong
Java_org_rocksdb_Logger_createNewLoggerOptions(JNIEnv
* env
, jobject jobj
,
232 auto* sptr_logger
= new std::shared_ptr
<ROCKSDB_NAMESPACE::LoggerJniCallback
>(
233 new ROCKSDB_NAMESPACE::LoggerJniCallback(env
, jobj
));
236 auto* options
= reinterpret_cast<ROCKSDB_NAMESPACE::Options
*>(joptions
);
237 sptr_logger
->get()->SetInfoLogLevel(options
->info_log_level
);
239 return GET_CPLUSPLUS_POINTER(sptr_logger
);
243 * Class: org_rocksdb_Logger
244 * Method: createNewLoggerDbOptions
247 jlong
Java_org_rocksdb_Logger_createNewLoggerDbOptions(JNIEnv
* env
,
250 auto* sptr_logger
= new std::shared_ptr
<ROCKSDB_NAMESPACE::LoggerJniCallback
>(
251 new ROCKSDB_NAMESPACE::LoggerJniCallback(env
, jobj
));
255 reinterpret_cast<ROCKSDB_NAMESPACE::DBOptions
*>(jdb_options
);
256 sptr_logger
->get()->SetInfoLogLevel(db_options
->info_log_level
);
258 return GET_CPLUSPLUS_POINTER(sptr_logger
);
262 * Class: org_rocksdb_Logger
263 * Method: setInfoLogLevel
266 void Java_org_rocksdb_Logger_setInfoLogLevel(JNIEnv
* /*env*/, jobject
/*jobj*/,
267 jlong jhandle
, jbyte jlog_level
) {
269 reinterpret_cast<std::shared_ptr
<ROCKSDB_NAMESPACE::LoggerJniCallback
>*>(
271 handle
->get()->SetInfoLogLevel(
272 static_cast<ROCKSDB_NAMESPACE::InfoLogLevel
>(jlog_level
));
276 * Class: org_rocksdb_Logger
277 * Method: infoLogLevel
280 jbyte
Java_org_rocksdb_Logger_infoLogLevel(JNIEnv
* /*env*/, jobject
/*jobj*/,
283 reinterpret_cast<std::shared_ptr
<ROCKSDB_NAMESPACE::LoggerJniCallback
>*>(
285 return static_cast<jbyte
>(handle
->get()->GetInfoLogLevel());
289 * Class: org_rocksdb_Logger
290 * Method: disposeInternal
293 void Java_org_rocksdb_Logger_disposeInternal(JNIEnv
* /*env*/, jobject
/*jobj*/,
296 reinterpret_cast<std::shared_ptr
<ROCKSDB_NAMESPACE::LoggerJniCallback
>*>(
298 delete handle
; // delete std::shared_ptr