Skip to content

Commit 3ce466a

Browse files
committed
Documentation update.
* Documentation update. * v1.0.0
1 parent fad6636 commit 3ce466a

7 files changed

Lines changed: 152 additions & 83 deletions

File tree

README.md

Lines changed: 57 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,8 @@
1414
![Coverage](.github/badges/jacoco.svg)
1515
![Branches](.github/badges/branches.svg)
1616

17-
[![Milestone](https://img.shields.io/github/milestones/progress-percent/mjfryc/mjaron-tinyloki-java/1?label=Next%20release:%20milestone-v0.4.0)](https://github.com/mjfryc/mjaron-tinyloki-java/milestone/1)
18-
19-
20-
Tiny [Grafana Loki](https://grafana.com/oss/loki/) client (log sender) written in pure Java 1.8 without any external dependencies.
17+
Tiny [Grafana Loki](https://grafana.com/oss/loki/) client (log sender) written in pure Java 1.8 without any external
18+
dependencies.
2119

2220
* Implements JSON variant of [Loki API](https://grafana.com/docs/loki/latest/api/#post-lokiapiv1push)
2321
* Works with **Android** and **Java SE**
@@ -28,26 +26,16 @@ Tiny [Grafana Loki](https://grafana.com/oss/loki/) client (log sender) written i
2826
HTTP sender requires http URL, optionally basic authentication credentials may be set.
2927

3028
Short example:
29+
3130
```java
3231
import pl.mjaron.tinyloki.*;
3332

3433
public class Sample {
3534
public static void main(String[] args) {
36-
37-
LogController tinyLoki = TinyLoki
38-
.withUrl("http://localhost/loki/api/v1/push")
39-
.withBasicAuth("user", "pass")
40-
.start();
41-
42-
ILogStream stream = tinyLoki.stream() // Before v0.3.2 use createStream()
43-
.info()
44-
.l("host", "MyComputerName")
45-
.l("customLabel", "custom_value")
46-
.build();
47-
48-
stream.log("Hello world.");
49-
50-
tinyLoki.softStop().hardStop();
35+
TinyLoki loki = TinyLoki.withUrl("http://localhost:3100").withBasicAuth("user", "pass").start();
36+
ILogStream helloStream = loki.stream().info().l("topic", "hello").build();
37+
helloStream.log("Hello world!");
38+
loki.closeSync();
5139
}
5240
}
5341
```
@@ -60,34 +48,51 @@ import pl.mjaron.tinyloki.*;
6048
public class Sample {
6149
public static void main(String[] args) {
6250

63-
// Initialize log controller instance with URL.
64-
// Usually creating more than one LogController instance doesn't make sense.
65-
// LogController owns separate thread which sends logs periodically.
66-
LogController tinyLoki = TinyLoki
67-
.withUrl("http://localhost/loki/api/v1/push")
68-
.withBasicAuth("user", "pass")
69-
.start();
70-
71-
// Create streams. It is thread-safe.
72-
ILogStream stream = tinyLoki.createStream(
73-
// Define stream labels...
74-
// Initializing log level to verbose and adding some custom labels.
75-
TinyLoki.verbose()
76-
.l("host", "MyComputerName") // Custom static label.
77-
.l("customLabel", "custom_value") // Custom static label.
78-
// Label names should start with letter
79-
// and contain letters, digits and '_' only.
80-
// Bad characters will be replaced by '_'.
81-
// If first character is bad, it will be replaced by 'A'.
82-
);
83-
84-
// ... new streams and other logs here (thread-safe, non-blocking).
85-
stream.log("Hello world.");
86-
87-
// Optionally flush logs before application exit.
88-
tinyLoki
89-
.softStop() // Try to send logs last time. Blocking method.
90-
.hardStop(); // If it doesn't work (soft timeout) - force stop sending thread.
51+
// Initialize the log controller instance with URL.
52+
// The endpoint loki/api/v1/push will be added by default if missing.
53+
// Usually creating more than one TinyLoki instance doesn't make sense.
54+
// TinyLoki (its default IExecutor implementation) owns separate thread which sends logs periodically.
55+
// It may be called inside try-with-resources block, but the default close() method doesn't synchronize the logs,
56+
// but just interrupts the background worker thread.
57+
try (TinyLoki loki = TinyLoki.withUrl("http://localhost:3100/loki/api/v1/push")
58+
// Print all diagnostic information coming from the TinyLoki library. For diagnostic purposes only.
59+
.withVerboseLogMonitor()
60+
61+
// Set the custom log processing interval time.
62+
// So the executor will try to send the next logs 10 seconds after the previous logs sending operation.
63+
.withThreadExecutor(10 * 1000)
64+
65+
// Set custom time of HTTP connection establishing timeout.
66+
.withConnectTimeout(10 * 1000)
67+
68+
// Encode the logs to limit the size of data sent.
69+
.withGzipLogEncoder()
70+
71+
// The BasicBuffering is set by default, but here the (not encoded) message size limit may be customized.
72+
.withBasicBuffering(3 * 1024 * 1024, 10)
73+
74+
// Initialize the library with above settings.
75+
// The ThreadExecutor will create a new thread and start waiting for the logs to be sent.
76+
.start()) {
77+
78+
// Some logs here...
79+
ILogStream whiteStream = loki.stream().l("color", "white").build();
80+
whiteStream.log("Hello white world.");
81+
82+
// Blocking method, tries to send the logs ASAP and wait for sending completion.
83+
// This method returns false when timeout occurs, but true when sending has completed with success or failure.
84+
boolean allHttpSendingOperationsFinished = loki.sync();
85+
System.out.println("Are all logs processed: " + allHttpSendingOperationsFinished);
86+
87+
ILogStream redStream = loki.stream().l("color", "red").build();
88+
redStream.log("Hello white world.");
89+
90+
// Blocking method, tries to synchronize the logs than interrupt and join the execution thread.
91+
// Set the custom timeout time for this operation.
92+
boolean closedWithSuccess = loki.closeSync(5 * 1000);
93+
94+
System.out.println("Synced and closed with success: " + closedWithSuccess);
95+
}
9196
}
9297
}
9398
```
@@ -97,11 +102,11 @@ public class Sample {
97102
### Maven Central
98103

99104
```gradle
100-
implementation 'io.github.mjfryc:mjaron-tinyloki-java:0.3.11'
105+
implementation 'io.github.mjfryc:mjaron-tinyloki-java:1.0.0'
101106
```
102107

103-
_[Maven Central page](https://search.maven.org/artifact/io.github.mjfryc/mjaron-tinyloki-java/),_
104-
_[Maven Central repository URL](https://repo1.maven.org/maven2/io/github/mjfryc/mjaron-tinyloki-java/)_
108+
_[Maven Central page](https://search.maven.org/artifact/io.github.mjfryc/mjaron-tinyloki-java/),_
109+
_[Maven Central repository URL](https://repo1.maven.org/maven2/io/github/mjfryc/mjaron-tinyloki-java/)_
105110

106111
### GitHub Packages
107112

@@ -114,10 +119,10 @@ Click the [Packages section](https://github.com/mjfryc?tab=packages&repo_name=mj
114119
3. Add this jar to project dependencies in build.gradle, e.g:
115120

116121
```gradle
117-
implementation files(project.rootDir.absolutePath + '/libs/mjaron-tinyloki-java-0.3.11.jar')
122+
implementation files(project.rootDir.absolutePath + '/libs/mjaron-tinyloki-java-1.0.0.jar')
118123
```
119124

120-
## API design
125+
## API design (outdated)
121126

122127
```mermaid
123128
classDiagram

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ plugins {
66
}
77

88
group 'io.github.mjfryc'
9-
version '0.3.11'
9+
version '1.0.0'
1010

1111
repositories {
1212
mavenCentral()

src/main/java/pl/mjaron/tinyloki/Settings.java

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,35 @@ public Settings withExecutor(final IExecutor executor) {
293293
return this;
294294
}
295295

296+
/**
297+
* Sets the new instance of {@link ThreadExecutor} with custom interval time between sending logs.
298+
* <p>
299+
* The default log processing interval time is defined by {@link ThreadExecutor#DEFAULT_PROCESSING_INTERVAL_TIME_MS}.
300+
*
301+
* @param processingIntervalTime Interval time between sending logs in milliseconds.
302+
* @return This {@link Settings} object reference.
303+
* @see ThreadExecutor#DEFAULT_PROCESSING_INTERVAL_TIME_MS
304+
* @since 1.0.0
305+
*/
306+
public Settings withThreadExecutor(final int processingIntervalTime) {
307+
return withExecutor(new ThreadExecutor(processingIntervalTime));
308+
}
309+
310+
/**
311+
* Sets the new instance of {@link ThreadExecutor} with default interval time between sending logs.
312+
* <p>
313+
* The default log processing interval time is defined by {@link ThreadExecutor#DEFAULT_PROCESSING_INTERVAL_TIME_MS}.
314+
* <p>
315+
* The {@link ThreadExecutor} is the default executor if no other executor is set.
316+
*
317+
* @return This {@link Settings} object reference.
318+
* @see ThreadExecutor#DEFAULT_PROCESSING_INTERVAL_TIME_MS
319+
* @since 1.0.0
320+
*/
321+
public Settings withThreadExecutor() {
322+
return withExecutor(new ThreadExecutor());
323+
}
324+
296325
/**
297326
* Allows setting the {@link IBuffering} implementation.
298327
*
@@ -308,10 +337,15 @@ public Settings withBuffering(final IBuffering buffering) {
308337
/**
309338
* Allows to set and configure the {@link BasicBuffering}.
310339
*
311-
* @param maxMessageSize The max single message size.
340+
* @param maxMessageSize The max single (not encoded) message size.
312341
* This size should be lower than the Grafana Loki server max message size.
342+
* <p>
313343
* The default value in this library: {@link IBuffering#DEFAULT_MAX_MESSAGE_SIZE}.
344+
* <p>
345+
* Note that if this size is exceeded, the server may respond with HTTP error <code>500</code>, e.g:
346+
* <pre>{@code rpc error: code = ResourceExhausted desc = grpc: received message larger than max (6331143 vs. 4194304)}</pre>
314347
* @param maxBuffersCount The max buffers count. The value should be tuned to target system capabilities.
348+
* <p>
315349
* The default value in this library: {@link IBuffering#DEFAULT_MAX_BUFFERS_COUNT}.
316350
* @return This {@link Settings} object reference.
317351
* @since 1.0.0

src/main/java/pl/mjaron/tinyloki/ThreadExecutor.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,24 @@
22

33
public class ThreadExecutor implements IExecutor, Runnable {
44

5-
public static final int DEFAULT_LOG_COLLECTION_PERIOD_MS = 5000;
5+
public static final int DEFAULT_PROCESSING_INTERVAL_TIME_MS = 5000;
66

77
private final BlockingLogListener logListener = new BlockingLogListener();
88
private ILogMonitor logMonitor = null;
99
private ILogCollector logCollector = null;
1010
private ILogProcessor logProcessor = null;
1111
private Thread workerThread = null;
12-
private int logCollectionPeriod = DEFAULT_LOG_COLLECTION_PERIOD_MS;
12+
private int processingIntervalTime = DEFAULT_PROCESSING_INTERVAL_TIME_MS;
1313

1414
public ThreadExecutor() {
1515
}
1616

17-
public ThreadExecutor(final int logCollectionPeriod) {
18-
this.logCollectionPeriod = logCollectionPeriod;
17+
public ThreadExecutor(final int processingIntervalTime) {
18+
this.processingIntervalTime = processingIntervalTime;
1919
}
2020

21-
public int getLogCollectionPeriod() {
22-
return logCollectionPeriod;
21+
public int getProcessingIntervalTime() {
22+
return processingIntervalTime;
2323
}
2424

2525
@Override
@@ -110,7 +110,7 @@ public void run() {
110110

111111
while (true) {
112112
try {
113-
final int anyLogs = logListener.waitForLogs(logCollectionPeriod);
113+
final int anyLogs = logListener.waitForLogs(processingIntervalTime);
114114
if (anyLogs > 0) {
115115
logProcessor.processLogs();
116116
}

src/main/java/pl/mjaron/tinyloki/TinyLoki.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -365,13 +365,14 @@ public boolean sync(final int timeout) throws InterruptedException {
365365
}
366366

367367
/**
368-
* Blocking function. BLocks the calling thread until all requested logs are processed (attempted to send) or default timeout occurs, defined as {@link #DEFAULT_SYNC_TIMEOUT}.
368+
* Blocking function. Blocks the calling thread until all requested logs are processed (attempted to send)
369+
* or default timeout occurs, defined as {@link #DEFAULT_SYNC_TIMEOUT}.
369370
* <p>
370371
* <b>Thread safety</b>
371372
* <p>
372373
* It may be called from any thread.
373374
*
374-
* @return <code>true</code> If sync operation finished with success.
375+
* @return <code>true</code> If sync operation finished, even if the HTTP operation has failed due to IO errors.
375376
* <p>
376377
* <code>false</code> If sync operation failed due to timeout.
377378
* @throws InterruptedException When calling thread is interrupted.

src/test/java/pl/mjaron/tinyloki/IntegrationTest.java

Lines changed: 48 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -24,31 +24,60 @@ public static boolean isIntegrationEnabled() {
2424

2525
@Test
2626
void shortExample() throws InterruptedException {
27-
TinyLoki loki = TinyLoki.withUrl("http://localhost:3100")
28-
.withBasicAuth("user", "pass")
29-
.start();
27+
TinyLoki loki = TinyLoki.withUrl("http://localhost:3100").withBasicAuth("user", "pass").start();
28+
ILogStream helloStream = loki.stream().info().l("topic", "hello").build();
29+
helloStream.log("Hello world!");
30+
loki.closeSync();
31+
}
3032

31-
ILogStream windowStream = loki.stream().info().l("device", "window").build();
32-
ILogStream doorStream = loki.stream().info().l("device", "door").build();
33+
@Test
34+
void verboseTest() throws InterruptedException {
3335

34-
windowStream.log("The window is open.");
35-
doorStream.log("The door is open.");
36+
// Initialize the log controller instance with URL.
37+
// The endpoint loki/api/v1/push will be added by default if missing.
38+
// Usually creating more than one TinyLoki instance doesn't make sense.
39+
// TinyLoki (its default IExecutor implementation) owns separate thread which sends logs periodically.
40+
// It may be called inside try-with-resources block, but the default close() method doesn't synchronize the logs,
41+
// but just interrupts the background worker thread.
42+
try (TinyLoki loki = TinyLoki.withUrl("http://localhost:3100/loki/api/v1/push")
3643

37-
// Time for syncing and closing the logs.
38-
boolean closedWithSuccess = loki.closeSync(1000);
44+
// Print all diagnostic information coming from the TinyLoki library. For diagnostic purposes only.
45+
.withVerboseLogMonitor()
3946

40-
System.out.println("Closed with success: " + closedWithSuccess);
47+
// Set the custom log processing interval time.
48+
// So the executor will try to send the next logs 10 seconds after the previous logs sending operation.
49+
.withThreadExecutor(10 * 1000)
4150

42-
assertTrue(closedWithSuccess);
43-
}
51+
// Set custom time of HTTP connection establishing timeout.
52+
.withConnectTimeout(10 * 1000)
4453

45-
@Test
46-
void sampleTest() throws InterruptedException {
47-
try (TinyLoki loki = TinyLoki.withUrl("http://localhost:3100/loki/api/v1/push").withVerboseLogMonitor().start()) {
48-
ILogStream stream = loki.stream().l("color", "white").build();
49-
stream.log("Hello world.");
50-
loki.sync();
51-
loki.stop();
54+
// Encode the logs to limit the size of data sent.
55+
.withGzipLogEncoder()
56+
57+
// The BasicBuffering is set by default, but here the (not encoded) message size limit may be customized.
58+
.withBasicBuffering(3 * 1024 * 1024, 10)
59+
60+
// Initialize the library with above settings.
61+
// The ThreadExecutor will create a new thread and start waiting for the logs to be sent.
62+
.start()) {
63+
64+
// Some logs here...
65+
ILogStream whiteStream = loki.stream().l("color", "white").build();
66+
whiteStream.log("Hello white world.");
67+
68+
// Blocking method, tries to send the logs ASAP and wait for sending completion.
69+
// This method returns false when timeout occurs, but true when sending has completed with success or failure.
70+
boolean allHttpSendingOperationsFinished = loki.sync();
71+
System.out.println("Are all logs processed: " + allHttpSendingOperationsFinished);
72+
73+
ILogStream redStream = loki.stream().l("color", "red").build();
74+
redStream.log("Hello white world.");
75+
76+
// Blocking method, tries to synchronize the logs than interrupt and join the execution thread.
77+
// Set the custom timeout time for this operation.
78+
boolean closedWithSuccess = loki.closeSync(5 * 1000);
79+
80+
System.out.println("Synced and closed with success: " + closedWithSuccess);
5281
}
5382
}
5483

src/test/java/pl/mjaron/tinyloki/ThreadExecutorTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ class ThreadExecutorTest {
1717
@Test
1818
void basic() throws InterruptedException {
1919
ThreadExecutor executor = new ThreadExecutor(1000);
20-
assertEquals(1000, executor.getLogCollectionPeriod());
20+
assertEquals(1000, executor.getProcessingIntervalTime());
2121
assertThrows(RuntimeException.class, () -> {
2222
executor.configure(null, new DummyLogProcessor(), new VerboseLogMonitor());
2323
});

0 commit comments

Comments
 (0)