Skip to content

Commit 1d1f30b

Browse files
committed
chore: add new blog post on efficient logging in Paper plugins using SLF4J, log4j2, and Grafana Loki
1 parent 9afd1c1 commit 1d1f30b

File tree

1 file changed

+136
-0
lines changed

1 file changed

+136
-0
lines changed
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
---
2+
title: 'Efficient Logging in Paper Plugins with SLF4J and log4j2'
3+
alternativeTitle: 'Marker-based logging for structured analysis'
4+
description: 'Learn how to use SLF4J and log4j2 markers to group logs by topic and make analysis easier.'
5+
pubDate: '2024-09-29'
6+
headerImage: 'images/blog/effizientes-logging-paper-plugins-slf4j-log4j2-grafana-loki.jpg'
7+
headerImageAlt: 'Efficient logging in Paper plugins with SLF4J and log4j2 Grafana Loki image'
8+
slug: 'efficient-logging-paper-plugins-slf4j-log4j2-grafana-loki'
9+
translationKey: 'effizientes-logging-paper-plugins-slf4j-log4j2-grafana-loki'
10+
canonical: 'https://onelitefeather.net/en/blog/efficient-logging-paper-plugins-slf4j-log4j2-grafana-loki'
11+
alternates:
12+
- hreflang: 'de'
13+
href: 'https://onelitefeather.net/de/blog/effizientes-logging-paper-plugins-slf4j-log4j2-grafana-loki'
14+
- hreflang: 'en'
15+
href: 'https://onelitefeather.net/en/blog/efficient-logging-paper-plugins-slf4j-log4j2-grafana-loki'
16+
- hreflang: 'x-default'
17+
href: 'https://onelitefeather.net/en/blog/efficient-logging-paper-plugins-slf4j-log4j2-grafana-loki'
18+
schemaOrg:
19+
- type: 'BlogPosting'
20+
headline: 'Efficient Logging in Paper Plugins with SLF4J and log4j2'
21+
alternativeHeadline: 'Marker-based logging for structured analysis'
22+
description: 'Learn how to use SLF4J and log4j2 markers to group logs by topic and make analysis easier.'
23+
author:
24+
type: 'Person'
25+
name: 'Phillipp Glanz'
26+
datePublished: '2024-09-29T00:00:00+00:00'
27+
---
28+
29+
When building a Minecraft plugin for PaperMC, it’s easy to lose track of logs. Traditional log messages quickly hit their limits in larger projects or multi-module architectures. All the more reason to add a clear structure that keeps important information filterable.
30+
<!--more-->
31+
In this post, we’ll show how to use SLF4J and `log4j2` markers to group your logs by topic. With this technique, you can tag log messages with labels like `DATABASE`, `NETWORK`, or `GAME`. That’s especially useful when your Paper setup has multiple modules—for database access, network calls, or game events. With deliberate log structuring, analyzing logs for debugging becomes much simpler.
32+
33+
### What are markers and why use them?
34+
35+
Markers are like small labels you add to your log messages. Instead of just writing “Database connection established,” you tag the message with the `DATABASE` marker. Later, in the console or tools like Grafana Loki, you can filter explicitly for that marker.
36+
37+
Another advantage: markers work independently of regular log levels such as INFO, WARN, or ERROR. You gain a thematic layer without changing your existing logging concept.
38+
39+
### Example implementation in a Paper plugin
40+
41+
**Step 1: Create a marker class**
42+
43+
Start by adding a central class for your marker constants. That keeps all markers in one place and reusable across modules.
44+
45+
```java
46+
import org.slf4j.Marker;
47+
import org.slf4j.MarkerFactory;
48+
49+
public final class LogMarkers {
50+
public static final Marker DATABASE = MarkerFactory.getMarker("DATABASE");
51+
public static final Marker GAME = MarkerFactory.getMarker("GAME");
52+
public static final Marker NETWORK = MarkerFactory.getMarker("NETWORK");
53+
54+
private LogMarkers() {}
55+
}
56+
```
57+
58+
**Step 2: Use markers in code**
59+
60+
Use markers in your code to categorize log messages. Here’s a database module example:
61+
62+
```java
63+
import org.slf4j.Logger;
64+
import org.slf4j.LoggerFactory;
65+
import static com.example.LogMarkers.*;
66+
67+
public class DatabaseModule {
68+
private static final Logger logger = LoggerFactory.getLogger(DatabaseModule.class);
69+
70+
public void connectToDatabase() {
71+
logger.info(DATABASE, "Successfully established database connection.");
72+
}
73+
74+
public void executeQuery(String query) {
75+
logger.debug(DATABASE, "SQL query: {}", query);
76+
try {
77+
// Execute DB query...
78+
} catch (Exception e) {
79+
logger.error(DATABASE, "Error executing query: {}", e.getMessage());
80+
}
81+
}
82+
}
83+
```
84+
85+
**Step 3: Adjust the `log4j2` configuration**
86+
87+
Limit console and file output to the relevant markers in `log4j2.xml`:
88+
89+
```xml
90+
<Configuration>
91+
<Appenders>
92+
<Console name="Console" target="SYSTEM_OUT">
93+
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %c{1} - %msg %marker%n"/>
94+
</Console>
95+
<File name="FileLogger" fileName="logs/paper-plugin.log">
96+
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} %-5p [%c{1}] %m %marker%n"/>
97+
</File>
98+
</Appenders>
99+
<Loggers>
100+
<Logger name="DatabaseLogger" level="debug" additivity="false">
101+
<MarkerFilter marker="DATABASE" onMatch="ACCEPT" onMismatch="DENY"/>
102+
<AppenderRef ref="Console"/>
103+
<AppenderRef ref="FileLogger"/>
104+
</Logger>
105+
<Logger name="GameLogger" level="debug" additivity="false">
106+
<MarkerFilter marker="GAME" onMatch="ACCEPT" onMismatch="DENY"/>
107+
<AppenderRef ref="Console"/>
108+
<AppenderRef ref="FileLogger"/>
109+
</Logger>
110+
<Root level="info">
111+
<AppenderRef ref="Console"/>
112+
<AppenderRef ref="FileLogger"/>
113+
</Root>
114+
</Loggers>
115+
</Configuration>
116+
```
117+
118+
With this setup, you limit console and file output to the markers you care about. That cuts noise and keeps attention on the important messages.
119+
120+
### Integration with Grafana Loki
121+
122+
By using markers, you can filter logs cleanly in Grafana Loki—group all database-related logs with `DATABASE` or game events with `GAME` and analyze them in a targeted way. This structure makes it easier to follow events and react to issues.
123+
124+
### Conclusion
125+
126+
Markers give your Paper plugin a clear logging architecture, making targeted analysis straightforward. Whether in the console, files, or Grafana Loki, marker filtering keeps you on top of what’s happening inside the plugin.
127+
128+
Want to learn more about Paper plugins? Stay tuned for future dev blogs covering additional techniques.
129+
130+
## Become Part of Our Journey
131+
132+
At OneLiteFeather, we value a relaxed working atmosphere and embrace the flair of creative freedom coupled with structured organization. We work according to the **Kanban principle**, which allows us to work in a stress-free environment without rigid deadlines. Our focus is on **active communication** and collective progress. If you have experience in **Moderation**, **Community Management**, **Development**, or **Concept Creation** and want to engage in a community that values personal growth and teamwork, then you are in the right place. References are welcome and help us gain a better understanding of your skills and experiences.
133+
134+
We look forward to hearing from you and realizing exciting projects together. You can reach me, **themeinerlp**, directly on Discord, or you can contact us through our Discord server at [1lf.link/discord](https://1lf.link/discord). There, you can open a ticket to apply. Alternatively, you can contact **OneLiteFeather** directly via Discord. Let's talk about your ideas and how you can contribute to the OneLiteFeather community. Together we can explore the digital world, expand our knowledge, and build a positive and supportive community.
135+
136+
If you have any questions, feel free to ask us. We are here to answer all your questions and look forward to learning more about you and your interests!

0 commit comments

Comments
 (0)