GithubHelp home page GithubHelp logo

sematext / sematext-logsene-android Goto Github PK

View Code? Open in Web Editor NEW
22.0 18.0 10.0 1.81 MB

Sematext Logs Client Library for Android

Home Page: https://sematext.com/logsene

License: Apache License 2.0

Java 100.00%
logging logs mobile-analytics monitoring logshipper android log-management

sematext-logsene-android's Introduction

SDK for Shipping Android Application Logs to Sematext

License

Sematext Logs is ELK as a Service. This library lets you collect mobile analytics and log data from your Android applications using Sematext. There is an equivalent library for shipping logs from iOS available. If you don't have a Sematext account, you can register for free to get your App token.

Use the Mobile Application Logs Integration to get out-of-the-box reports with the most important information about your mobile applications.

Get an overview of your mobile apps with information like:

  • top Android versions
  • top log severities and version names

Mobile Logpack Overview

Explore the common errors associated with your mobile applications and see an aggregated error view including:

  • number of errors and theirs count over time
  • top operating systems, top Android versions that are reporting errors
  • error log events

Mobile Logpack Errors

Get insights from dedicated Android report that include:

  • mobile operating system logs count histogram and their count
  • top severities, versions, version codes, and version names
  • mobile applications log events

Mobile Logpack Android

Getting Started

If you haven't already, register for a free account. Create a new Logs App to get the App token, you will need it later.

Add the following gradle dependency to your Android application:

allprojects {
 repositories {
    mavenCentral()
    maven { url "https://jitpack.io" }
 }
}

dependencies {
    compile 'com.github.sematext:sematext-logsene-android:3.2.0'
}

The library sends data to Sematext servers, so you will need to add the INTERNET and ACCESS_NETWORK_STATE permissions to your application manifest.

<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>

The library sends data in batches to preserve battery (every 15 minutes), or if there are more than 10 events queued up. Events are saved while the device is offline so you don't have to worry about losing any data. By default the library keeps up to 5,000 events while offline.

Add the following inside the application manifest (inside <application>):

 <meta-data
   android:name="LogseneAppToken"
   android:value="yourtoken" />
 <meta-data
   android:name="LogseneType"
   android:value="example" />

 <!-- For EU region use https://logsene-receiver.eu.sematext.com as the receiverUrl -->
 <meta-data
   android:name="LogseneReceiverUrl"
   android:value="https://logsene-receiver.sematext.com" />
  • LogseneAppToken (required): This is your Logs App token, you should have received one after registering and creating your Logs App. We highly recommend creating a write-only token in your app settings to prevent any unauthorized access to your logs.
  • LogseneType (required): Type to be used for all events (Sematext Logs uses Elasticsearch compatible API)
  • LogseneMaxOfflineMessages: Maximum number of offline stored events. Events are stored on the device while it's offline, or if the library is unable to send them to Sematext for some reason.
  • LogseneReceiverUrl: If you are using Sematext Enterprise, you can put your Logsene Receiver URL here. For EU region please use https://logsene-receiver.eu.sematext.com as the receiverUrl.
  • LogseneMinTimeDelay: Minimum amount of time (in milliseconds) to wait between sending logs while application is running and creating new log messages
  • LogseneInterval: time interval (in milliseconds) for sending logs regardless of app being active (minimum 15 minutes)
  • LogseneRequiresUnmeteredNetwork: if logs should be shipped only on unmetered network connection
  • LogseneRequiresDeviceIdle: if logs should be shipped only when device is idle
  • LogseneRequiresBatteryNotLow: if logs should be shipped only when battery is not low
  • LogseneAutomaticLocationEnabled: if logs should be automatically enriched with device location information. See the Enriching Logs with Location section for more details.

Example Application

To see how some basic use cases are actually implemented, checkout the bundled TestApp android application. Make sure to set your own App token in the Android manifest.

Note that it's highly recommended that you use one instance of Logsene at any time in your app.

Initializing Logsene

Starting with version 3.0.0 of the Android library Logsene needs to be initialized in a static way in order to be used. This allows usage in classes that don't have Context available. To do that, you need to call the following in your application code. Keep in mind this is only needed once:

Logsene.init(this);

To get the instance of the Logsene object that supports logging you need to call the getInstance() method, for example:

Logsene logsene = Logsene.getInstance();
logsene.info("Hello World!");

Mobile Application Analytics

With Sematext you get Elasticsearch and Kibana out of the box, which makes it great for mobile analytics. Once you've setup the Logsene service, it's trivial to start sending custom events. For example, you may want to send an event every time a user starts an activity. In that case you could put the following inside the onCreate() method:

try {
    JSONObject event = new JSONObject();
    event.put("activity", this.getClass().getSimpleName());
    event.put("action", "started");
    Logsene logsene = Logsene.getInstance();
    logsene.event(event);
} catch (JSONException e) {
    Log.e("myapp", "Unable to construct json", e);
}

To visualize the collected data, you would use the integrated Kibana dashboard or Sematext native UI.

If you don't see the events in the dashboard immediately, note that data are sent in batches to preserve the battery (every 60s), or if there are more than 10 events queued up. Events are saved while the device is offline, so you don't have to worry about losing any data.

When it comes to the structure of your events, you are free to choose your own, the above is just an example. You can use any number of fields, and you can use nested fields. Basically, any valid JSON object will work fine. Note that the meta field is reserved for meta information (see Meta Fields below). If you set a value for this field when sending an event, the meta information will not be included for that event.

Meta Fields

Meta data are added to each event, all stored within the "meta" field:

  • versionName (as defined in your build.gradle)
  • versionCode (as defined in your build.gradle)
  • osRelease (android version)
  • uuid (unique identifier for this app installation)

You can set your own meta fields with Logsene.setDefaultMeta(). For example:

try {
    JSONObject meta = new JSONObject();
    meta.put("user", "[email protected]");
    Logsene.setDefaultMeta(meta);
} catch (JSONException e) {
    Log.e("myapp", "Unable to construct json", e);
}

Note that these meta fields are global, and will be attached to every event sent to Sematext.

Pausing & Resuming Logs Sending

The library can be instructed to stop sending logs on demand. To do that you need to call the following function:

logsene.pause();

Logs sending can be resumed by calling the following function:

logsene.resume();

Note that the logs that are in the buffer and were waiting to be sent at the time of pausing will not be sent until the logs sending process is resumed.

Centralized Logging

The library offers some basic functions for centralized logging:

  • Logsene.debug(String)
  • Logsene.info(String)
  • Logsene.warn(String)
  • Logsene.warn(Throwable)
  • Logsene.error(String)
  • Logsene.error(Throwable)

For integrating with existing logging frameworks, see below.

Enriching Logs with Location

Logs can be enriched with location data manually and automatically. For manual enriching the library supports the following methods:

  • Logsene.debug(String, Double, Double)
  • Logsene.info(String, Double, Double)
  • Logsene.warn(String, Double, Double)
  • Logsene.warn(Throwable, Double, Double)
  • Logsene.error(String, Double, Double)
  • Logsene.error(Throwable, Double, Double)

For example:

logsene.info("Hello World with Location!", 53.08, 23.08);

It is also possible to tell the library to automatically retrieve location from the device. In such case the Logsene object instance needs to be created in the following way:

Logsene.init(this);
Logsene logsene = Logsene.getInstance();
logsene.initializeLocationListener(context);

Because of the automatic retrieval of location from the device the ACCESS_COARSE_LOCATION and ACCESS_FINE_LOCATION permissions are needed:

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>

It is also crucial to call the initializeLocationListener(Context context) method of the Logsene object after the user gives the application the permission to use location data. Otherwise it will not work. Example on how that can be done is included in the com.sematext.logseneandroid.MainActivity class.

JUL

If your application uses JUL (java.util.logging) loggers, you can use the provided custom Handler for Logsene. You will need to configure it through code, since we need a reference to the Context object. If you configure your loggers to use the LogseneHandler, all log messages will be sent to Sematext for centralized logging.

Logsene.init(this);
Logsene logsene = Logsene.getInstance();
Logger logger = Logger.getLogger("mylogger");
logger.addHandler(new LogseneHandler(logsene));

Using this SDK with Timber and Timber.Tree

Timber is a logger with a small, extensible API which provides utility on top of Android's normal Log class. To use Timber with this SDK for shipping Android logs to Sematext have a look at https://github.com/JakeWharton/timber/blob/master/timber-sample/src/main/java/com/example/timber/ExampleApp.java. You can extend Timber.Tree and overwrite the log method and include logging using the Logsene object there. Simply initialize the Logsene object in the onCreate method and everything should work from that point.

Logging exceptions

If you use JUL and the LogseneHandler, all logged exceptions will be sent to Sematext, no further configuration is needed. However, if you don't use JUL, the library provides a helper method to log exceptions:

Logsene.init(this);
Logsene logsene = Logsene.getInstance();
try {
    trySomeOperation();
} catch (IOException e) {
    logsene.error(e);
}

How to log uncaught exceptions (crashes)

You can log any uncaught exceptions by defining your own uncaught exception handler. You will need to define a custom Application class for this to work. For example:

public class TestApplication extends Application {
    private Thread.UncaughtExceptionHandler defaultExceptionHandler;
    private Thread.UncaughtExceptionHandler exceptionHandler = new Thread.UncaughtExceptionHandler() {
        @Override
        public void uncaughtException(Thread thread, Throwable ex) {
            // Send uncaught exception to Logsene.
            Logsene.init(TestApplication.this);
            Logsene logsene = Logsene.getInstance();
            logsene.error(ex);

            // Run the default android handler if one is set
            if (defaultExceptionHandler != null) {
                defaultExceptionHandler.uncaughtException(thread, ex);
            }
        }
    };

    public TestApplication() {
        defaultExceptionHandler = Thread.getDefaultUncaughtExceptionHandler();
        Thread.setDefaultUncaughtExceptionHandler(exceptionHandler);
    }
}

Don't forget to declare the custom application class in your manifest (with android:name on application element).

Migrating to version 3.1 from previous versions

Starting from version 3.1.0 Logsene Android SDK is no longer displaying the prompt to enable location services and provide appropriate rights. It is now the responsibility of the application itself.

Migrating to version 3.x from 2.x

Starting from version 3.0.0 Logsene Android SDK contains backwards incompatible changes related to how it is initialized. You no longer need to create the Logsene object everytime you would like to use it for logging. You no longer create the Logsene object itself like this:

Logsene logsene = new Logsene(context, true);

Instead you call the init(Context) method once and retrieve the instance of Logsene object later:

Logsene.init(context);
Logsene logsene = Logsene.getInstance();

You also need to include the LogseneAutomaticLocationEnabled property in your manifest file to enable automatic log enrichment with location data:

<meta-data
    android:name="LogseneAutomaticLocationEnabled"
    android:value="true" />

sematext-logsene-android's People

Contributors

amir-hadzic avatar cesarferreira avatar gr0 avatar kim-low avatar otisg avatar tloten avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sematext-logsene-android's Issues

KitKat support

Hello, Sematext team. I found out that its project works perfectly on KitKat (ye, there are still apps supporting KitKat). What do you think about downgrading minSdkVersion to 19?

Make batch size configurable

Min batch size is currently not configurable, it might be useful to make it configurable as different apps might have different message sizes.

Please use jCenter, not maven

jCenter is now and has been for a while the standard repo expected by gradle on Android. See this blog post.

PS: The Tor Norbye quoted at the end is the head honcho for Android Studio.

Fatal Exception: java.lang.RuntimeException CONNECTIVITY_CHANGE crash

There is a crash when network state changes. Mostly it happens on Android 5 devices (minSdkVersion 21 in my project).

Logs below

Fatal Exception: java.lang.RuntimeException: Error receiving broadcast Intent { act=android.net.conn.CONNECTIVITY_CHANGE flg=0x4000010 (has extras) } in androidx.work.impl.constraints.trackers.NetworkStateTracker$NetworkStateBroadcastReceiver@d734889
       at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:982)
       at android.os.Handler.handleCallback(Handler.java:739)
       at android.os.Handler.dispatchMessage(Handler.java:95)
       at android.os.Looper.loop(Looper.java:145)
       at android.app.ActivityThread.main(ActivityThread.java:6872)
       at java.lang.reflect.Method.invoke(Method.java)
       at java.lang.reflect.Method.invoke(Method.java:372)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1404)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1199)
As i understand you just need to upgrade your WorkManager lib version to the latest one.

Caused by java.util.concurrent.RejectedExecutionException: Task java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask@89daab0 rejected from java.util.concurrent.ScheduledThreadPoolExecutor@29437d29[Terminated, pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0]
       at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2011)
       at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:793)
       at java.util.concurrent.ScheduledThreadPoolExecutor.delayedExecute(ScheduledThreadPoolExecutor.java:298)
       at java.util.concurrent.ScheduledThreadPoolExecutor.schedule(ScheduledThreadPoolExecutor.java:503)
       at java.util.concurrent.Executors$DelegatedScheduledExecutorService.schedule(Executors.java:644)
       at androidx.work.impl.background.systemalarm.WorkTimer.startTimer(WorkTimer.java:82)
       at androidx.work.impl.background.systemalarm.DelayMetCommandHandler.onAllConstraintsMet(DelayMetCommandHandler.java:100)
       at androidx.work.impl.constraints.WorkConstraintsTracker.onConstraintMet(WorkConstraintsTracker.java:150)
       at androidx.work.impl.constraints.controllers.ConstraintController.updateCallback(ConstraintController.java:134)
       at androidx.work.impl.constraints.controllers.ConstraintController.onConstraintChanged(ConstraintController.java:141)
       at androidx.work.impl.constraints.trackers.ConstraintTracker.setState(ConstraintTracker.java:103)
       at androidx.work.impl.constraints.trackers.NetworkStateTracker$NetworkStateBroadcastReceiver.onReceive(NetworkStateTracker.java:170)
       at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:972)
       at android.os.Handler.handleCallback(Handler.java:739)
       at android.os.Handler.dispatchMessage(Handler.java:95)
       at android.os.Looper.loop(Looper.java:145)
       at android.app.ActivityThread.main(ActivityThread.java:6872)
       at java.lang.reflect.Method.invoke(Method.java)
       at java.lang.reflect.Method.invoke(Method.java:372)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1404)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1199)

This ussie as i understand is related to an old WorkManager library version which need to be updated. Here is what i found accourding this issue https://stackoverflow.com/questions/55530714/java-util-concurrent-rejectedexecutionexception-when-using-workmanager
Crash is not happening when i disable Logsene.
Please take a look at it.

implementation "android.arch.work:work-runtime:1.0.0"

WorkManager not working on Baidu Push SDK

Hi,

I use Sematext with Baidu Push SDK , but happen issue of " WorkManager is not initialized properly. The most likely cause is that you disabled WorkManagerInitializer in your manifest but forgot to call WorkManager#initialize in your Application#onCreate or a ContentProvider.".

I'm guess Baidu push provider use android:process=":bdservice_v1" the reason for the crash. Is there a solution please help me?

Upgrade Logsene Android SDK to work on SDK version 29 and 30

An exception is raised when calling Logsene.init(context) during App init with the stack below.
No trace of WorkManager on the getStarted.

Using Android Target SDK 29 and logsene 3.0.0.

2021-05-31 17:51:50.076 20205-20205/com.enterprise.edetect E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.enterprise.edetect, PID: 20205
    java.lang.RuntimeException: Unable to instantiate application com.enterprise.edetect.view.AppDelegate: java.lang.IllegalStateException: WorkManager is not initialized properly.  The most likely cause is that you disabled WorkManagerInitializer in your manifest but forgot to call WorkManager#initialize in your Application#onCreate or a ContentProvider.
        at android.app.LoadedApk.makeApplication(LoadedApk.java:1226)
        at android.app.ActivityThread.handleBindApplication(ActivityThread.java:6594)
        at android.app.ActivityThread.access$1600(ActivityThread.java:231)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1952)
        at android.os.Handler.dispatchMessage(Handler.java:107)
        at android.os.Looper.loop(Looper.java:214)
        at android.app.ActivityThread.main(ActivityThread.java:7682)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:516)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)
     Caused by: java.lang.IllegalStateException: WorkManager is not initialized properly.  The most likely cause is that you disabled WorkManagerInitializer in your manifest but forgot to call WorkManager#initialize in your Application#onCreate or a ContentProvider.
        at androidx.work.WorkManager.getInstance(WorkManager.java:141)
        at com.sematext.logseneandroid.Logsene.schedulePeriodicWorker(Logsene.java:473)
        at com.sematext.logseneandroid.Logsene.init(Logsene.java:110)
        at com.enterprise.edetect.view.AppDelegate.setupServices(AppDelegate.kt:65)
        at com.enterprise.edetect.view.AppDelegate.attachBaseContext(AppDelegate.kt:34)
        at android.app.Application.attach(Application.java:390)
        at android.app.Instrumentation.newApplication(Instrumentation.java:1154)
        at android.app.LoadedApk.makeApplication(LoadedApk.java:1218)
        at android.app.ActivityThread.handleBindApplication(ActivityThread.java:6594) 
        at android.app.ActivityThread.access$1600(ActivityThread.java:231) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1952) 
        at android.os.Handler.dispatchMessage(Handler.java:107) 
        at android.os.Looper.loop(Looper.java:214) 
        at android.app.ActivityThread.main(ActivityThread.java:7682) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:516) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950) 

Same user got this 86 times in 1 day: Fatal Exception: android.database.sqlite.SQLiteException

Fatal Exception: android.database.sqlite.SQLiteException: no such column: ١ (code 1 SQLITE_ERROR[1]): , while compiling: DELETE FROM objects WHERE `id` IN (SELECT `id` FROM objects ORDER BY `id` ASC limit ١);
       at android.database.sqlite.SQLiteConnection.nativePrepareStatement(SQLiteConnection.java)
       at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:1372)
       at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:811)
       at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:590)
       at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:62)
       at android.database.sqlite.SQLiteStatement.<init>(SQLiteStatement.java:33)
       at android.database.sqlite.SQLiteDatabase.executeSql(SQLiteDatabase.java:2321)
       at android.database.sqlite.SQLiteDatabase.execSQL(SQLiteDatabase.java:2249)
       at com.sematext.logseneandroid.SqliteObjectQueue.remove(SqliteObjectQueue.java:138)
       at com.sematext.logseneandroid.SqliteObjectQueue.add(SqliteObjectQueue.java:104)
       at com.sematext.logseneandroid.Logsene.addToQueue(Logsene.java:322)
       at com.sematext.logseneandroid.Logsene.event(Logsene.java:234)

phone: Galaxy S10
android version: 10

        <meta-data
            android:name="LogseneReceiverUrl"
            android:value="https://logsene-receiver.eu.sematext.com" />

Dependency error

Using logseme will add a dependency on com.google.android:android:4.1.1.4 to your gradle project. This is wrong. If you want to keep logsene as a maven-based project at least add <scope>provided</scope> to the android dependency declaration.

Can `logsene` object be used as a static variable?

This is more of a design question

Is it possible to use logsene like other logging frameworks? There's a design problem with the demo application provided: it constructs a new Logsene object on the activity, this means that it's hard to log in other classes that are not activities.

For a logging library, what's common is to be able to use static methods to log: Example in crashlytics, example in Timber. They all use static methods to log.
Is there any way to accomplish this with Logsene? what i tried was creating a class like this

public class Log {

    private static final FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance();
    private static Logsene logsene;

    public static void initLogsene(Context context) {
        logsene = new Logsene(context);
    }

    public static void e(String tag, String message, Throwable exception) {
        android.util.Log.e(tag, message, exception);
        crashlytics.log(message);

        if (logsene != null) {
            logsene.error(tag + ':' + message);
            logsene.error(exception);
        }
    }

But this seems to create a memory leak due to the static Logsene field, which holds a reference to the context passed in the constructor. The warning is

Do not place Android context classes in static fields (static reference to Logsene which has field context pointing to Context); this is a memory leak

What is the recommended way here? how can I log from a class that doesn't have a context available?

Logstash support?

Hi, I noticed that this android library sends data to Logsene servers. Is it possible to send data to Logstash servers?

Log messages are sent (or received?) in the wrong order

I've noticed this since day 1 of using sematext. Sometimes the android app sends messages that I know in the code have to be A..B and I see them in the sematext console as B..A

I'm not really sure if this is a problem in the android SDK or in your backend or in the UI but given that the SDK is the originator of the data, I created the ticket here to start as much downstream as possible before going up.

Finally, I've noticed that when this happens, the timestamp of both messages is the same (field @timestamp in the json), so maybe the bug comes from not having enough precision in the android clock. Having said that, there are ways around this, like a serial number or some other method to break the tie in two messages with the same timestamp

Exception - Not allowed to start service Intent - caused by startService call

We are getting continuous Fatal exception from our Crashlytics, with a reference to this line in the ExceptionStack...
com.sematext.android.Logsene.sendServiceIntent (SourceFile:143)
Fatal Exception: java.lang.IllegalStateExceptionNot allowed to start service Intent { cmp=com./com.sematext.android.LogseneService (has extras) }: app is in background uid UidRecord{ TRNB idle change:uncached procs:2 proclist:****,18907, seq(0,0,0)} com.sematext.android.Logsene.sendServiceIntent

It seems to be coming from here:

https://stackoverflow.com/questions/46445265/android-8-0-java-lang-illegalstateexception-not-allowed-to-start-service-inten seems to point out there is some change in behaviour in different Android versions and people have shared their solutions.

We should change this and make a new release.

Investigate potential memory leaks

From a user:

On the memory leak, it seems the issue was more Android-related.

We only made three changes overall:

  • Closing cursors after accessing the SQLite Database
  • ObjectDBHelper changed to static
  • Updated the okhttp dependency version

The issues were probably being caused by okhttp, but to be safe we made the aforementioned changes.

Unable to index all documents. Response: {"took":1,"errors":true,"items":[]}

Keep getting this errors on our app, it's been working fine for like a year

2020-10-01 16:14:09.937 D/Logsene: Worker started, message queue size = 4
2020-10-01 16:14:09.938 D/Logsene: Attempting to send bulk request
2020-10-01 16:14:10.090 E/Logsene: Unable to index all documents. Response: {"took":1,"errors":true,"items":[]}
    Request: 
2020-10-01 16:14:10.094 D/Logsene: Worker succeeded in sending logs, message queue size = 4
2020-10-01 16:14:10.097 I/WM-WorkerWrapper: Worker result SUCCESS for Work [ id=1bceb32c-2217-4fe4-9b17-720440bffbeb, tags={ com.sematext.logseneandroid.LogWorker, com.sematext.android.LogWorker.interval } ]
2020-10-01 16:29:22.161 D/Logsene: Worker started, message queue size = 4
2020-10-01 16:29:22.162 D/Logsene: Attempting to send bulk request
2020-10-01 16:29:22.293 E/Logsene: Unable to index all documents. Response: {"took":1,"errors":true,"items":[]}
    Request: 
2020-10-01 16:29:22.297 D/Logsene: Worker succeeded in sending logs, message queue size = 4
2020-10-01 16:29:22.300 I/WM-WorkerWrapper: Worker result SUCCESS for Work [ id=1bceb32c-2217-4fe4-9b17-720440bffbeb, tags={ com.sematext.logseneandroid.LogWorker, com.sematext.android.LogWorker.interval } ]
2020-10-01 16:44:09.930 D/Logsene: Worker started, message queue size = 4
2020-10-01 16:44:09.931 D/Logsene: Attempting to send bulk request
2020-10-01 16:44:10.088 E/Logsene: Unable to index all documents. Response: {"took":1,"errors":true,"items":[]}
    Request: 
2020-10-01 16:44:10.092 D/Logsene: Worker succeeded in sending logs, message queue size = 4

Integrating LogSene Library

Hi LogSene Team, I'm trying to integrate the Library in my App with Min SDK version 16 while syncing my gradle file it throws an error "Manifest merger failed : uses-sdk:minSdkVersion 19 cannot be smaller than version 21 declared in library [com.github.sematext:sematext-logsene-android:2.1.0]". How to resolve this as we have user below SDK Version 21.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.