Initialize glog in react native

Reviewed By: andreicoman11

Differential Revision: D3023912

fb-gh-sync-id: 0f240448f465fd0ad629c239f45a24f01af4dc1b
shipit-source-id: 0f240448f465fd0ad629c239f45a24f01af4dc1b
This commit is contained in:
Chris Hopman 2016-03-10 06:01:26 -08:00 committed by Facebook Github Bot 0
parent d20bde3f2e
commit e9c79f85ba
8 changed files with 204 additions and 3 deletions

View File

@ -6,7 +6,6 @@
import os
# Example: react_native_target('java/com/facebook/react/common:common')
def react_native_target(path):
return '//ReactAndroid/src/main/' + path
@ -34,6 +33,8 @@ JSC_INTERNAL_DEPS = [
'//native/third-party/jsc-internal:jsc_legacy_profiler',
]
FBGLOGINIT_TARGET = '//ReactAndroid/src/main/jni/first-party/fbgloginit:fbgloginit'
INTERNAL_APP = 'PUBLIC'
# React property preprocessor
@ -96,4 +97,4 @@ def robolectric3_test(name, deps, vm_args=None, *args, **kwargs):
vm_args=vm_args + extra_vm_args,
*args,
**kwargs
)
)

View File

@ -0,0 +1,24 @@
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
glog_init.cpp
LOCAL_C_INCLUDES := $(LOCAL_PATH)
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)
LOCAL_CFLAGS := -fexceptions -fno-omit-frame-pointer
LOCAL_CFLAGS += -Wall -Werror
CXX11_FLAGS := -std=gnu++11
LOCAL_CFLAGS += $(CXX11_FLAGS)
LOCAL_EXPORT_CPPFLAGS := $(CXX11_FLAGS)
LOCAL_LDLIBS := -llog
LOCAL_SHARED_LIBRARIES := libglog
LOCAL_MODULE := libglog_init
include $(BUILD_SHARED_LIBRARY)

View File

@ -0,0 +1,19 @@
cxx_library(
name = 'fbgloginit',
srcs = [
'glog_init.cpp',
],
exported_headers = ['fb/glog_init.h'],
compiler_flags = [
'-fexceptions',
'-fno-omit-frame-pointer',
],
linker_flags = [
'-llog',
],
deps=[
'//xplat/third-party/glog:glog',
],
visibility=['PUBLIC'],
)

View File

@ -0,0 +1,11 @@
// Copyright 2004-present Facebook. All Rights Reserved.
#pragma once
#include <string>
namespace facebook { namespace gloginit {
void initialize(const char* tag = "ReactNativeJNI");
}}

View File

@ -0,0 +1,142 @@
// Copyright 2004-present Facebook. All Rights Reserved.
#include "fb/glog_init.h"
#include <iostream>
#include <mutex>
#include <stdexcept>
#include <glog/logging.h>
#ifdef __ANDROID__
#include <android/log.h>
static int toAndroidLevel(google::LogSeverity severity) {
switch (severity) {
case google::GLOG_INFO:
return ANDROID_LOG_INFO;
case google::GLOG_WARNING:
return ANDROID_LOG_WARN;
case google::GLOG_ERROR:
return ANDROID_LOG_ERROR;
case google::GLOG_FATAL:
return ANDROID_LOG_FATAL;
default:
return ANDROID_LOG_FATAL;
}
}
/**
* Sends GLog output to adb logcat.
*/
class LogcatSink : public google::LogSink {
public:
void send(
google::LogSeverity severity,
const char* full_filename,
const char* base_filename,
int line,
const struct ::tm* tm_time,
const char* message,
size_t message_len) override {
auto level = toAndroidLevel(severity);
__android_log_print(
level,
base_filename,
"%.*s",
(int)message_len,
message);
}
};
/**
* Sends GLog output to adb logcat.
*/
class TaggedLogcatSink : public google::LogSink {
const std::string tag_;
public:
TaggedLogcatSink(const std::string &tag) : tag_{tag} {}
void send(
google::LogSeverity severity,
const char* full_filename,
const char* base_filename,
int line,
const struct ::tm* tm_time,
const char* message,
size_t message_len) override {
auto level = toAndroidLevel(severity);
__android_log_print(
level,
tag_.c_str(),
"%.*s",
(int)message_len,
message);
}
};
static google::LogSink* make_sink(const std::string& tag) {
if (tag.empty()) {
return new LogcatSink{};
} else {
return new TaggedLogcatSink{tag};
}
}
static void sendGlogOutputToLogcat(const char* tag) {
google::AddLogSink(make_sink(tag));
// Disable logging to files
for (auto i = 0; i < google::NUM_SEVERITIES; ++i) {
google::SetLogDestination(i, "");
}
}
#endif // __ANDROID__
static void lastResort(const char* tag, const char* msg, const char* arg = nullptr) {
#ifdef __ANDROID__
if (!arg) {
__android_log_write(ANDROID_LOG_ERROR, tag, msg);
} else {
__android_log_print(ANDROID_LOG_ERROR, tag, "%s: %s", msg, arg);
}
#else
std::cerr << msg;
if (arg) {
std::cerr << ": " << arg;
}
std::cerr << std::endl;
#endif
}
namespace facebook { namespace gloginit {
void initialize(const char* tag) {
static std::once_flag flag{};
static auto failed = false;
std::call_once(flag, [tag] {
try {
google::InitGoogleLogging(tag);
#ifdef __ANDROID__
sendGlogOutputToLogcat(tag);
#endif
} catch (std::exception& ex) {
lastResort(tag, "Failed to initialize glog", ex.what());
failed = true;
} catch (...) {
lastResort(tag, "Failed to initialize glog");
failed = true;
}
});
if (failed) {
throw std::runtime_error{"Failed to initialize glog"};
}
}
}}

View File

@ -23,7 +23,7 @@ LOCAL_CFLAGS += $(CXX11_FLAGS)
LOCAL_EXPORT_CPPFLAGS := $(CXX11_FLAGS)
LOCAL_LDLIBS += -landroid
LOCAL_SHARED_LIBRARIES := libfolly_json libfbjni libjsc
LOCAL_SHARED_LIBRARIES := libfolly_json libfbjni libjsc libglog_init
LOCAL_STATIC_LIBRARIES := libreactnative
include $(BUILD_SHARED_LIBRARY)
@ -31,5 +31,6 @@ include $(BUILD_SHARED_LIBRARY)
$(call import-module,react)
$(call import-module,jsc)
$(call import-module,folly)
$(call import-module,fbgloginit)
$(call import-module,jni)
$(call import-module,jsc)

View File

@ -4,6 +4,7 @@ include_defs('//ReactAndroid/DEFS')
SUPPORTED_PLATFORMS = '^android-(armv7|x86)$'
DEPS = [
FBGLOGINIT_TARGET,
'//native/jni:jni',
'//native/third-party/android-ndk:android',
'//xplat/folly:molly',

View File

@ -3,6 +3,7 @@
#include <android/asset_manager_jni.h>
#include <android/input.h>
#include <fb/log.h>
#include <fb/glog_init.h>
#include <folly/json.h>
#include <jni/Countable.h>
#include <jni/Environment.h>
@ -907,6 +908,7 @@ jmethodID getLogMarkerMethod() {
extern "C" JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
return initialize(vm, [] {
facebook::gloginit::initialize();
// Inject some behavior into react/
ReactMarker::logMarker = bridge::logMarker;
WebWorkerUtil::createWebWorkerThread = WebWorkers::createWebWorkerThread;