Python logging #7

Merged
akinwale merged 5 commits from python-logging into master 2017-08-18 00:06:58 +02:00
11 changed files with 225 additions and 82 deletions
Showing only changes of commit 0e4f7e951f - Show all commits

View file

@ -7,7 +7,7 @@ import sh
class LbryBootstrap(Bootstrap): class LbryBootstrap(Bootstrap):
name = 'lbry' name = 'lbry'
recipe_depends = ['sdl2', ('python2', 'python3crystax')] recipe_depends = ['genericndkbuild', ('python2', 'python3crystax')]
def run_distribute(self): def run_distribute(self):
info_main('# Creating Android project from build and {} bootstrap'.format( info_main('# Creating Android project from build and {} bootstrap'.format(

View file

@ -0,0 +1,21 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
allprojects {
repositories {
jcenter()
}
}
buildscript {
repositories {
jcenter()
}
dependencies {
classpath "com.android.tools.build:gradle-experimental:0.7.0"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}

View file

@ -0,0 +1,21 @@
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
# Default value: -Xmx10248m -XX:MaxPermSize=256m
# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
android.useDeprecatedNdk=true
org.gradle.jvmargs=-Xmx4096M

View file

@ -4,19 +4,18 @@ include $(CLEAR_VARS)
LOCAL_MODULE := main LOCAL_MODULE := main
SDL_PATH := ../SDL #SDL_PATH := ../SDL
LOCAL_C_INCLUDES := $(LOCAL_PATH)/$(SDL_PATH)/include #LOCAL_C_INCLUDES := $(LOCAL_PATH)/$(SDL_PATH)/include
# Add your application source files here... # Add your application source files here...
LOCAL_SRC_FILES := $(SDL_PATH)/src/main/android/SDL_android_main.c \ LOCAL_SRC_FILES := pyjniusjni.c start.c
start.c
LOCAL_CFLAGS += -I$(LOCAL_PATH)/../../../../other_builds/$(PYTHON2_NAME)/$(ARCH)/python2/python-install/include/python2.7 $(EXTRA_CFLAGS) LOCAL_CFLAGS += -I$(LOCAL_PATH)/../../../../other_builds/$(PYTHON2_NAME)/$(ARCH)/python2/python-install/include/python2.7 $(EXTRA_CFLAGS)
LOCAL_SHARED_LIBRARIES := SDL2 python_shared LOCAL_SHARED_LIBRARIES := python_shared
LOCAL_LDLIBS := -lGLESv1_CM -lGLESv2 -llog $(EXTRA_LDLIBS) LOCAL_LDLIBS := -llog $(EXTRA_LDLIBS)
LOCAL_LDFLAGS += -L$(LOCAL_PATH)/../../../../other_builds/$(PYTHON2_NAME)/$(ARCH)/python2/python-install/lib $(APPLICATION_ADDITIONAL_LDFLAGS) LOCAL_LDFLAGS += -L$(LOCAL_PATH)/../../../../other_builds/$(PYTHON2_NAME)/$(ARCH)/python2/python-install/lib $(APPLICATION_ADDITIONAL_LDFLAGS)

View file

@ -6,7 +6,7 @@ LOCAL_MODULE := main
LOCAL_SRC_FILES := YourSourceHere.c LOCAL_SRC_FILES := YourSourceHere.c
LOCAL_STATIC_LIBRARIES := SDL2_static #LOCAL_STATIC_LIBRARIES := SDL2_static
include $(BUILD_SHARED_LIBRARY) include $(BUILD_SHARED_LIBRARY)
$(call import-module,SDL)LOCAL_PATH := $(call my-dir) $(call import-module,SDL)LOCAL_PATH := $(call my-dir)

View file

@ -0,0 +1,103 @@
#include <pthread.h>
#include <jni.h>
#define LOGI(...) do {} while (0)
#define LOGE(...) do {} while (0)
#include "android/log.h"
/* These JNI management functions are taken from SDL2, but modified to refer to pyjnius */
/* #define LOG(n, x) __android_log_write(ANDROID_LOG_INFO, (n), (x)) */
/* #define LOGP(x) LOG("python", (x)) */
#define LOG_TAG "Python_android"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
/* Function headers */
JNIEnv* Android_JNI_GetEnv(void);
static void Android_JNI_ThreadDestroyed(void*);
static pthread_key_t mThreadKey;
static JavaVM* mJavaVM;
int Android_JNI_SetupThread(void)
{
Android_JNI_GetEnv();
return 1;
}
/* Library init */
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved)
{
JNIEnv *env;
mJavaVM = vm;
LOGI("JNI_OnLoad called");
if ((*mJavaVM)->GetEnv(mJavaVM, (void**) &env, JNI_VERSION_1_4) != JNI_OK) {
LOGE("Failed to get the environment using GetEnv()");
return -1;
}
/*
* Create mThreadKey so we can keep track of the JNIEnv assigned to each thread
* Refer to http://developer.android.com/guide/practices/design/jni.html for the rationale behind this
*/
if (pthread_key_create(&mThreadKey, Android_JNI_ThreadDestroyed) != 0) {
__android_log_print(ANDROID_LOG_ERROR, "pyjniusjni", "Error initializing pthread key");
}
Android_JNI_SetupThread();
return JNI_VERSION_1_4;
}
JNIEnv* Android_JNI_GetEnv(void)
{
/* From http://developer.android.com/guide/practices/jni.html
* All threads are Linux threads, scheduled by the kernel.
* They're usually started from managed code (using Thread.start), but they can also be created elsewhere and then
* attached to the JavaVM. For example, a thread started with pthread_create can be attached with the
* JNI AttachCurrentThread or AttachCurrentThreadAsDaemon functions. Until a thread is attached, it has no JNIEnv,
* and cannot make JNI calls.
* Attaching a natively-created thread causes a java.lang.Thread object to be constructed and added to the "main"
* ThreadGroup, making it visible to the debugger. Calling AttachCurrentThread on an already-attached thread
* is a no-op.
* Note: You can call this function any number of times for the same thread, there's no harm in it
*/
JNIEnv *env;
int status = (*mJavaVM)->AttachCurrentThread(mJavaVM, &env, NULL);
if(status < 0) {
LOGE("failed to attach current thread");
return 0;
}
/* From http://developer.android.com/guide/practices/jni.html
* Threads attached through JNI must call DetachCurrentThread before they exit. If coding this directly is awkward,
* in Android 2.0 (Eclair) and higher you can use pthread_key_create to define a destructor function that will be
* called before the thread exits, and call DetachCurrentThread from there. (Use that key with pthread_setspecific
* to store the JNIEnv in thread-local-storage; that way it'll be passed into your destructor as the argument.)
* Note: The destructor is not called unless the stored value is != NULL
* Note: You can call this function any number of times for the same thread, there's no harm in it
* (except for some lost CPU cycles)
*/
pthread_setspecific(mThreadKey, (void*) env);
return env;
}
static void Android_JNI_ThreadDestroyed(void* value)
{
/* The thread is being destroyed, detach it from the Java VM and set the mThreadKey value to NULL as required */
JNIEnv *env = (JNIEnv*) value;
if (env != NULL) {
(*mJavaVM)->DetachCurrentThread(mJavaVM);
pthread_setspecific(mThreadKey, NULL);
}
}
void *WebView_AndroidGetJNIEnv()
{
return Android_JNI_GetEnv();
}

View file

@ -14,9 +14,7 @@
#include <sys/types.h> #include <sys/types.h>
#include <errno.h> #include <errno.h>
#include "SDL.h"
#include "android/log.h" #include "android/log.h"
#include "SDL_opengles2.h"
#define ENTRYPOINT_MAXLEN 128 #define ENTRYPOINT_MAXLEN 128
#define LOG(n, x) __android_log_write(ANDROID_LOG_INFO, (n), (x)) #define LOG(n, x) __android_log_write(ANDROID_LOG_INFO, (n), (x))

View file

@ -0,0 +1,59 @@
apply plugin: 'com.android.model.application'
model {
android {
compileSdkVersion {{ args.sdk_version }}
buildToolsVersion "23.0.3"
defaultConfig {
applicationId "{{ args.package }}"
minSdkVersion.apiLevel {{ args.min_sdk_version }}
targetSdkVersion.apiLevel {{ args.sdk_version }}
versionCode {{ args.numeric_version }}
versionName "{{ args.version }}"
buildConfigFields {
create() {
type "int"
name "VALUE"
value "1"
}
}
}
ndk {
abiFilters.add("armeabi-v7a")
moduleName = "main"
toolchain = "gcc"
toolchainVersion = "4.9"
platformVersion = 16
stl = "gnustl_shared"
renderscriptNdkMode = false
CFlags.add("-I" + file("src/main/jni/include/python2.7"))
ldFlags.add("-L" + file("src/main/jni/lib"))
ldLibs.addAll(["log", "python2.7"])
}
// Configures source set directory.
sources {
main {
jniLibs {
dependencies {
library "gnustl_shared"
// add pre-built libraries here and locate them below:
}
}
}
}
}
repositories {
libs(PrebuiltLibraries) {
gnustl_shared {
binaries.withType(SharedLibraryBinary) {
sharedLibraryFile = file("src/main/jniLibs/${targetPlatform.getName()}/libgnustl_shared.so")
}
}
// more here
}
}
}
// normal project dependencies here

View file

@ -9,7 +9,7 @@ class PyjniusRecipe(CythonRecipe):
version = 'master' version = 'master'
url = 'https://github.com/kivy/pyjnius/archive/{version}.zip' url = 'https://github.com/kivy/pyjnius/archive/{version}.zip'
name = 'pyjnius' name = 'pyjnius'
depends = [('python2', 'python3crystax'), ('sdl2', 'sdl', 'genericndkbuild'), 'six'] depends = [('python2', 'python3crystax'), 'genericndkbuild', 'six']
site_packages_name = 'jnius' site_packages_name = 'jnius'
call_hostpython_via_targetpython = False call_hostpython_via_targetpython = False

View file

@ -1,50 +1,6 @@
import platform import platform
# logging override (until we can figure out why logging doesn't work normally) import logging.handlers
import logging
from kivy.logger import Logger
class InternalLogger(logging.Logger):
def __init__(self, name, level=logging.DEBUG):
self.name = name
return super(InternalLogger, self).__init__(name, level)
def debug(self, msg, *args, **kwargs):
msg = '%s: %s' % (self.name, msg)
Logger.debug(msg, *args, **kwargs)
def info(self, msg, *args, **kwargs):
msg = '%s: %s' % (self.name, msg)
Logger.info(msg, *args, **kwargs)
def warning(self, msg, *args, **kwargs):
msg = '%s: %s' % (self.name, msg)
Logger.warning(msg, *args, **kwargs)
def error(self, msg, *args, **kwargs):
msg = '%s: %s' % (self.name, msg)
Logger.error(msg, *args, **kwargs)
def critical(self, msg, *args, **kwargs):
msg = '%s: %s' % (self.name, msg)
Logger.critical(msg, *args, **kwargs)
def log(self, lvl, msg, *args, **kwargs):
msg = '%s: %s' % (self.name, msg)
Logger.log(lvl, msg, *args, **kwargs)
def exception(self, msg, *args, **kwargs):
msg = '%s: %s' % (self.name, msg)
Logger.exception(msg, *args, **kwargs)
# required by twisted for some reason.
def fail(self, *args, **kwargs):
pass
def getLoggerOverride(name='root', loglevel=logging.DEBUG):
return InternalLogger(name, loglevel)
logging.getLogger = getLoggerOverride
from lbrynet.core import log_support from lbrynet.core import log_support
from twisted.internet import defer, reactor from twisted.internet import defer, reactor
@ -56,12 +12,10 @@ from lbrynet.core import utils, system_info
from lbrynet.daemon.auth.client import LBRYAPIClient from lbrynet.daemon.auth.client import LBRYAPIClient
from lbrynet.daemon.DaemonServer import DaemonServer from lbrynet.daemon.DaemonServer import DaemonServer
import kivy
import ssl import ssl
# Fixes / patches / overrides # Fixes / patches / overrides
# platform.platform() in libc_ver: IOError: [Errno 21] Is a directory # platform.platform() in libc_ver: IOError: [Errno 21] Is a directory
if (kivy.platform == 'android'):
from jnius import autoclass from jnius import autoclass
util = autoclass('io.lbry.lbrynet.Utils') util = autoclass('io.lbry.lbrynet.Utils')
platform.platform = lambda: 'Android %s (API %s)' % (util.getAndroidRelease(), util.getAndroidSdk()) platform.platform = lambda: 'Android %s (API %s)' % (util.getAndroidRelease(), util.getAndroidSdk())

View file

@ -1,20 +1,10 @@
from kivy.app import App
from kivy.lang import Builder
from kivy.utils import platform
kv = '''
Button:
text: 'push me!'
'''
class ServiceApp(App): class ServiceApp(App):
def build(self): def build(self):
if platform == 'android':
from jnius import autoclass from jnius import autoclass
Intent = autoclass('android.content.Intent') Intent = autoclass('android.content.Intent')
LbrynetService = autoclass('io.lbry.lbrynet.LbrynetService') LbrynetService = autoclass('io.lbry.lbrynet.LbrynetService')
context = autoclass('org.kivy.android.PythonActivity').mActivity #context = autoclass('org.kivy.android.PythonActivity').mActivity
#LbrynetService.start(context, '') #LbrynetService.start(context, '')
@ -22,7 +12,5 @@ class ServiceApp(App):
# ideally, we should have some form of service control for the activity # ideally, we should have some form of service control for the activity
#context.finish() #context.finish()
return Builder.load_string(kv)
if __name__ == '__main__': if __name__ == '__main__':
ServiceApp().run() ServiceApp().run()