]>
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
9 #include "include/org_rocksdb_Logger.h"
13 #include "rocksjni/loggerjnicallback.h"
14 #include "rocksjni/portal.h"
18 LoggerJniCallback::LoggerJniCallback(JNIEnv
* env
, jobject jlogger
)
19 : JniCallback(env
, jlogger
) {
20 m_jLogMethodId
= LoggerJni::getLogMethodId(env
);
21 if (m_jLogMethodId
== nullptr) {
22 // exception thrown: NoSuchMethodException or OutOfMemoryError
26 jobject jdebug_level
= InfoLogLevelJni::DEBUG_LEVEL(env
);
27 if (jdebug_level
== nullptr) {
28 // exception thrown: NoSuchFieldError, ExceptionInInitializerError
29 // or OutOfMemoryError
32 m_jdebug_level
= env
->NewGlobalRef(jdebug_level
);
33 if (m_jdebug_level
== nullptr) {
34 // exception thrown: OutOfMemoryError
38 jobject jinfo_level
= InfoLogLevelJni::INFO_LEVEL(env
);
39 if (jinfo_level
== nullptr) {
40 // exception thrown: NoSuchFieldError, ExceptionInInitializerError
41 // or OutOfMemoryError
44 m_jinfo_level
= env
->NewGlobalRef(jinfo_level
);
45 if (m_jinfo_level
== nullptr) {
46 // exception thrown: OutOfMemoryError
50 jobject jwarn_level
= InfoLogLevelJni::WARN_LEVEL(env
);
51 if (jwarn_level
== nullptr) {
52 // exception thrown: NoSuchFieldError, ExceptionInInitializerError
53 // or OutOfMemoryError
56 m_jwarn_level
= env
->NewGlobalRef(jwarn_level
);
57 if (m_jwarn_level
== nullptr) {
58 // exception thrown: OutOfMemoryError
62 jobject jerror_level
= InfoLogLevelJni::ERROR_LEVEL(env
);
63 if (jerror_level
== nullptr) {
64 // exception thrown: NoSuchFieldError, ExceptionInInitializerError
65 // or OutOfMemoryError
68 m_jerror_level
= env
->NewGlobalRef(jerror_level
);
69 if (m_jerror_level
== nullptr) {
70 // exception thrown: OutOfMemoryError
74 jobject jfatal_level
= InfoLogLevelJni::FATAL_LEVEL(env
);
75 if (jfatal_level
== nullptr) {
76 // exception thrown: NoSuchFieldError, ExceptionInInitializerError
77 // or OutOfMemoryError
80 m_jfatal_level
= env
->NewGlobalRef(jfatal_level
);
81 if (m_jfatal_level
== nullptr) {
82 // exception thrown: OutOfMemoryError
86 jobject jheader_level
= InfoLogLevelJni::HEADER_LEVEL(env
);
87 if (jheader_level
== nullptr) {
88 // exception thrown: NoSuchFieldError, ExceptionInInitializerError
89 // or OutOfMemoryError
92 m_jheader_level
= env
->NewGlobalRef(jheader_level
);
93 if (m_jheader_level
== nullptr) {
94 // exception thrown: OutOfMemoryError
99 void LoggerJniCallback::Logv(const char* /*format*/, va_list /*ap*/) {
100 // We implement this method because it is virtual but we don't
101 // use it because we need to know about the log level.
104 void LoggerJniCallback::Logv(const InfoLogLevel log_level
, const char* format
,
106 if (GetInfoLogLevel() <= log_level
) {
107 // determine InfoLogLevel java enum instance
110 case rocksdb::InfoLogLevel::DEBUG_LEVEL
:
111 jlog_level
= m_jdebug_level
;
113 case rocksdb::InfoLogLevel::INFO_LEVEL
:
114 jlog_level
= m_jinfo_level
;
116 case rocksdb::InfoLogLevel::WARN_LEVEL
:
117 jlog_level
= m_jwarn_level
;
119 case rocksdb::InfoLogLevel::ERROR_LEVEL
:
120 jlog_level
= m_jerror_level
;
122 case rocksdb::InfoLogLevel::FATAL_LEVEL
:
123 jlog_level
= m_jfatal_level
;
125 case rocksdb::InfoLogLevel::HEADER_LEVEL
:
126 jlog_level
= m_jheader_level
;
129 jlog_level
= m_jfatal_level
;
133 assert(format
!= nullptr);
134 assert(ap
!= nullptr);
135 const std::unique_ptr
<char[]> msg
= format_str(format
, ap
);
137 // pass msg to java callback handler
138 jboolean attached_thread
= JNI_FALSE
;
139 JNIEnv
* env
= getJniEnv(&attached_thread
);
140 assert(env
!= nullptr);
142 jstring jmsg
= env
->NewStringUTF(msg
.get());
143 if (jmsg
== nullptr) {
144 // unable to construct string
145 if (env
->ExceptionCheck()) {
146 env
->ExceptionDescribe(); // print out exception to stderr
148 releaseJniEnv(attached_thread
);
151 if (env
->ExceptionCheck()) {
152 // exception thrown: OutOfMemoryError
153 env
->ExceptionDescribe(); // print out exception to stderr
154 env
->DeleteLocalRef(jmsg
);
155 releaseJniEnv(attached_thread
);
159 env
->CallVoidMethod(m_jcallback_obj
, m_jLogMethodId
, jlog_level
, jmsg
);
160 if (env
->ExceptionCheck()) {
162 env
->ExceptionDescribe(); // print out exception to stderr
163 env
->DeleteLocalRef(jmsg
);
164 releaseJniEnv(attached_thread
);
168 env
->DeleteLocalRef(jmsg
);
169 releaseJniEnv(attached_thread
);
173 std::unique_ptr
<char[]> LoggerJniCallback::format_str(const char* format
,
177 va_copy(ap_copy
, ap
);
178 const size_t required
=
179 vsnprintf(nullptr, 0, format
, ap_copy
) + 1; // Extra space for '\0'
182 std::unique_ptr
<char[]> buf(new char[required
]);
184 va_copy(ap_copy
, ap
);
185 vsnprintf(buf
.get(), required
, format
, ap_copy
);
190 LoggerJniCallback::~LoggerJniCallback() {
191 jboolean attached_thread
= JNI_FALSE
;
192 JNIEnv
* env
= getJniEnv(&attached_thread
);
193 assert(env
!= nullptr);
195 if (m_jdebug_level
!= nullptr) {
196 env
->DeleteGlobalRef(m_jdebug_level
);
199 if (m_jinfo_level
!= nullptr) {
200 env
->DeleteGlobalRef(m_jinfo_level
);
203 if (m_jwarn_level
!= nullptr) {
204 env
->DeleteGlobalRef(m_jwarn_level
);
207 if (m_jerror_level
!= nullptr) {
208 env
->DeleteGlobalRef(m_jerror_level
);
211 if (m_jfatal_level
!= nullptr) {
212 env
->DeleteGlobalRef(m_jfatal_level
);
215 if (m_jheader_level
!= nullptr) {
216 env
->DeleteGlobalRef(m_jheader_level
);
219 releaseJniEnv(attached_thread
);
222 } // namespace rocksdb
225 * Class: org_rocksdb_Logger
226 * Method: createNewLoggerOptions
229 jlong
Java_org_rocksdb_Logger_createNewLoggerOptions(JNIEnv
* env
, jobject jobj
,
231 auto* sptr_logger
= new std::shared_ptr
<rocksdb::LoggerJniCallback
>(
232 new rocksdb::LoggerJniCallback(env
, jobj
));
235 auto* options
= reinterpret_cast<rocksdb::Options
*>(joptions
);
236 sptr_logger
->get()->SetInfoLogLevel(options
->info_log_level
);
238 return reinterpret_cast<jlong
>(sptr_logger
);
242 * Class: org_rocksdb_Logger
243 * Method: createNewLoggerDbOptions
246 jlong
Java_org_rocksdb_Logger_createNewLoggerDbOptions(JNIEnv
* env
,
249 auto* sptr_logger
= new std::shared_ptr
<rocksdb::LoggerJniCallback
>(
250 new rocksdb::LoggerJniCallback(env
, jobj
));
253 auto* db_options
= reinterpret_cast<rocksdb::DBOptions
*>(jdb_options
);
254 sptr_logger
->get()->SetInfoLogLevel(db_options
->info_log_level
);
256 return reinterpret_cast<jlong
>(sptr_logger
);
260 * Class: org_rocksdb_Logger
261 * Method: setInfoLogLevel
264 void Java_org_rocksdb_Logger_setInfoLogLevel(JNIEnv
* /*env*/, jobject
/*jobj*/,
265 jlong jhandle
, jbyte jlog_level
) {
267 reinterpret_cast<std::shared_ptr
<rocksdb::LoggerJniCallback
>*>(jhandle
);
268 handle
->get()->SetInfoLogLevel(
269 static_cast<rocksdb::InfoLogLevel
>(jlog_level
));
273 * Class: org_rocksdb_Logger
274 * Method: infoLogLevel
277 jbyte
Java_org_rocksdb_Logger_infoLogLevel(JNIEnv
* /*env*/, jobject
/*jobj*/,
280 reinterpret_cast<std::shared_ptr
<rocksdb::LoggerJniCallback
>*>(jhandle
);
281 return static_cast<jbyte
>(handle
->get()->GetInfoLogLevel());
285 * Class: org_rocksdb_Logger
286 * Method: disposeInternal
289 void Java_org_rocksdb_Logger_disposeInternal(JNIEnv
* /*env*/, jobject
/*jobj*/,
292 reinterpret_cast<std::shared_ptr
<rocksdb::LoggerJniCallback
>*>(jhandle
);
293 delete handle
; // delete std::shared_ptr