Skip to content

Commit

Permalink
Initialize glog in react native.
Browse files Browse the repository at this point in the history
Reviewed By: mhorowitz

Differential Revision: D2967180

fb-gh-sync-id: fe59b7f7c7dab8b5e7f3a449e72b467e1c2c2c67
shipit-source-id: fe59b7f7c7dab8b5e7f3a449e72b467e1c2c2c67
  • Loading branch information
cjhopman authored and facebook-github-bot-5 committed Feb 24, 2016
1 parent a759131 commit 11843fd
Show file tree
Hide file tree
Showing 8 changed files with 205 additions and 3 deletions.
5 changes: 3 additions & 2 deletions ReactAndroid/DEFS
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -96,4 +97,4 @@ def robolectric3_test(name, deps, vm_args=None, *args, **kwargs):
vm_args=vm_args + extra_vm_args,
*args,
**kwargs
)
)
24 changes: 24 additions & 0 deletions ReactAndroid/src/main/jni/first-party/fbgloginit/Android.mk
Original file line number Diff line number Diff line change
@@ -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)
20 changes: 20 additions & 0 deletions ReactAndroid/src/main/jni/first-party/fbgloginit/BUCK
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
cxx_library(
name = 'fbgloginit',
force_static = True,
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'],
)

11 changes: 11 additions & 0 deletions ReactAndroid/src/main/jni/first-party/fbgloginit/fb/glog_init.h
Original file line number Diff line number Diff line change
@@ -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");

}}
142 changes: 142 additions & 0 deletions ReactAndroid/src/main/jni/first-party/fbgloginit/glog_init.cpp
Original file line number Diff line number Diff line change
@@ -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"};
}
}

}}
3 changes: 2 additions & 1 deletion ReactAndroid/src/main/jni/react/jni/Android.mk
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,14 @@ 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)

$(call import-module,react)
$(call import-module,jsc)
$(call import-module,folly)
$(call import-module,fbgloginit)
$(call import-module,jni)
$(call import-module,jsc)
1 change: 1 addition & 0 deletions ReactAndroid/src/main/jni/react/jni/BUCK
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down
2 changes: 2 additions & 0 deletions ReactAndroid/src/main/jni/react/jni/OnLoad.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -845,6 +846,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;
Expand Down

0 comments on commit 11843fd

Please sign in to comment.