Giter Site home page Giter Site logo

mjfryc / mjaron-tinyloki-java Goto Github PK

View Code? Open in Web Editor NEW
10.0 2.0 6.0 264 KB

Tiny Grafana Loki client (log sender) written in pure Java 1.8 without any dependencies.

License: MIT License

Java 100.00%
loki grafana java java-8 java8 android-library android logging logger grafana-loki

mjaron-tinyloki-java's Introduction

mjaron-tinyloki-java

Java CI with Gradle Gradle Package CodeQL Maven Central Known Vulnerabilities Code Quality Total alerts Coverage Branches

Tiny Grafana Loki client (log sender) written in pure Java 1.8 without any external dependencies.

  • Implements JSON variant of Loki API
  • Works with Android and Java SE
  • Thread safe

API description

HTTP sender requires http URL, optionally basic authentication credentials may be set.

Short example:

import pl.mjaron.tinyloki.*;

public class Sample {
    public static void main(String[] args) {

        LogController logController = TinyLoki
                .withUrl("http://localhost/loki/api/v1/push")
                .withBasicAuth("user", "pass")
                .start();

        ILogStream stream = logController.stream() // Before v0.3.2 use createStream()
                .info()
                .l("host", "MyComputerName")
                .l("customLabel", "custom_value")
                .build();

        stream.log("Hello world.");

        logController.softStop().hardStop();
    }
}

Verbose example:

import pl.mjaron.tinyloki.*;

public class Sample {
    public static void main(String[] args) {

        // Initialize log controller instance with URL.
        // Usually creating more than one LogController instance doesn't make sense.
        // LogController owns separate thread which sends logs periodically.
        LogController logController = TinyLoki
                .withUrl("http://localhost/loki/api/v1/push")
                .withBasicAuth("user", "pass")
                .start();

        // Create streams. It is thread-safe.
        ILogStream stream = logController.createStream(
                // Define stream labels...
                // Initializing log level to verbose and adding some custom labels.
                TinyLoki.verbose()
                        .l("host", "MyComputerName")        // Custom static label.
                        .l("customLabel", "custom_value")   // Custom static label.
                // Label names should start with letter
                //     and contain letters, digits and '_' only.
                // Bad characters will be replaced by '_'.
                //     If first character is bad, it will be replaced by 'A'.
        );

        // ... new streams and other logs here (thread-safe, non-blocking).
        stream.log("Hello world.");

        // Optionally flush logs before application exit.
        logController
                .softStop()     // Try to send logs last time. Blocking method.
                .hardStop();    // If it doesn't work (soft timeout) - force stop sending thread.
    }
}

Integration

Maven Central

    implementation 'io.github.mjfryc:mjaron-tinyloki-java:0.3.11'

Maven Central page, Maven Central repository URL

GitHub Packages

Click the Packages section on the right.

Download directly

  1. Click the Packages section on the right.
  2. Find and download jar package from files list to e.g. your_project_root/libs dir.
  3. Add this jar to project dependencies in build.gradle, e.g:
    implementation files(project.rootDir.absolutePath + '/libs/mjaron-tinyloki-java-0.3.11.jar')

API design

classDiagram
class Labels {
    l(name, value) // Add the label
}

class ILogStream {
    <<Interface>>
    log(content)
    log(timestamp, content)
    release()
}

class ILogCollector {
    <<Interface>>
    createStream(labels)
    collect()
    contentType()
    waitForLogs(timeout)
}

class ILogEncoder {
    <<Interface>>
    contentEncoding(): String
    encode(final byte[] what): byte[]
}

class ILogMonitor {
    <<Interface>>
    onConfigured(contentType, contentEncoding)
    onEncoded(in, out)
    send(message)
    sendOk(status)
    sendErr(status, message)
    onException(exception)
    onWorkerThreadExit(isSoft)
}

class ILogSender {
    <<Interface>>
    configure(logSenderSettings, logMonitor)
    send(bytes)
}

class LogController {
    workerThread: Thread
    stream(): StreamBuilder
    createStream(labels)
    start()
    softStop()
    hardStop()
}

class GzipLogEncoder

class VerboseLogMonitor
class ErrorLogmonitor
class JsonLogStream
class JsonLogCollector

class Settings {
    +start(): LogController
}

class TinyLoki {
    +withUrl(url)$
}

VerboseLogMonitor --|> ILogMonitor: implements
ErrorLogmonitor --|> ILogMonitor: implements

ILogStream <.. ILogCollector: create
ILogCollector --* LogController
Labels <.. ILogCollector : use
ILogSender --* LogController
GzipLogEncoder --|> ILogEncoder: implements
ILogEncoder --* LogController
ILogMonitor --* LogController
JsonLogStream --|>  ILogStream: implements
JsonLogCollector --|> ILogCollector: implements
JsonLogStream <.. JsonLogCollector: create
HttpLogSender --|> ILogSender: implements
DummyLogSender --|> ILogSender: implements
Settings <.. TinyLoki: create
LogController <.. Settings: create

mjaron-tinyloki-java's People

Contributors

azplanlos avatar github-actions[bot] avatar mjfryc avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

mjaron-tinyloki-java's Issues

Implement label length limit

Loki Server may not accept logs due to label length limit.

Grafana Loki server configuration with default label length limits:

https://grafana.com/docs/loki/latest/configuration/

# Maximum length of a label name.
# CLI flag: -validation.max-length-label-name
[max_label_name_length: <int> | default = 1024]

# Maximum length of a label value.
# CLI flag: -validation.max-length-label-value
[max_label_value_length: <int> | default = 2048]

Separate the worker thread from `LogController`

Worker thread - periodic action of log collecting - should be separated, by:

  • Extracting interface of any worker thread, e.g. IWorker
  • Write IWorker implementation with single thread, named WorkerThread
  • Write WorkerReactiveX implementation which use rx-java instead of separated thread. Add it as different java project [In future, not covered by this issue].
  • Re-thing about softStop() and hardStop() methods implementation.
  • Re-thing how to implement it, to give possibility to implement #3.

Make Prettification optional

Hi, I have added the builder methods withPrettify() and withoutPrettify() to Labels (locally) as my labels value were being corrupted and I couldn't link between Loki and Tempo.

I tested and it would seem that Loki can now (v2.6.1) accept unprettified labels/values.

Do you think this is a good idea?

Paul.

Class Labels overrides equals but not hashCode.

@SuppressWarnings("unused")
public class Labels implements Cloneable {
Class Labels overrides [equals](https://lgtm.com/projects/g/mjfryc/mjaron-tinyloki-java/snapshot/d3f67ecc523b952ef7c612d302fab279b3ed770e/files/src/main/java/pl/mjaron/tinyloki/Labels.java#xd72d4c252d47884:1) but not hashCode.

Enable Gzip content encoding by default

  • There is no reason to skip Gzip content encoding
  • Skipping encoding make any sense for diagnostic purposes only
  • It is a functional change - it requires minor version update

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.