11# AGENTS.md - elf4j-engine
22
3- An asynchronous Java log engine implementing the ELF4J API. Java 21+, Maven build, MIT license.
3+ Asynchronous Java log engine implementing the ELF4J API. Java 21+, Maven build, MIT license.
44
55## Build Commands
66
@@ -33,90 +33,66 @@ An asynchronous Java log engine implementing the ELF4J API. Java 21+, Maven buil
3333## Code Style
3434
3535- ** Java 21** - uses records, pattern matching in ` instanceof ` , switch expressions, ` String.formatted() `
36- - ** Formatter** : Spotless with Palantir Java Format 2.87.0 (Google style). Runs automatically during ` process-sources ` . Always run ` ./mvnw spotless:apply ` before committing.
36+ - ** Formatter** : Spotless with Palantir Java Format 2.87.0 (Google style). Always run ` ./mvnw spotless:apply ` before committing.
3737
3838### Imports
3939
40- - Static imports first: ` import static org.junit.jupiter.api.Assertions.* `
41- - Then ` java.* ` , ` javax.* ` , external libs, then internal ` elf4j.* `
42- - Use static imports for test assertions and Mockito BDD methods
40+ Static imports first: ` import static org.junit.jupiter.api.Assertions.* ` . Then ` java.* ` , ` javax.* ` , external libs, then internal ` elf4j.* ` .
4341
4442### Naming Conventions
4543
46- | Element | Convention | Example |
47- | ----------------------| ------------------| --------------------------------------|
48- | Classes/Records | PascalCase | ` NativeLogger ` , ` LogEvent ` |
49- | Methods/Variables | camelCase | ` isEnabled() ` , ` logHandler ` |
50- | Constants | UPPER_SNAKE_CASE | ` DEFAULT_THROWABLE_MESSAGE ` |
51- | Packages | lowercase | ` elf4j.engine.logging ` |
52- | Test Classes | ` *Test ` suffix | ` NativeLoggerTest ` |
53- | Test Methods | camelCase verb | ` instanceForDifferentLevel() ` |
54- | Nested Test Classes | camelCase | ` class atLevels {} ` , ` class render {} ` |
44+ | Element | Convention | Example |
45+ | ---------| ------------| ---------|
46+ | Classes/Records | PascalCase | ` NativeLogger ` , ` LogEvent ` |
47+ | Methods/Variables | camelCase | ` isEnabled() ` , ` logHandler ` |
48+ | Constants | UPPER_SNAKE_CASE | ` DEFAULT_MESSAGE ` |
49+ | Packages | lowercase | ` elf4j.engine.logging ` |
50+ | Test Classes | ` *Test ` suffix | ` NativeLoggerTest ` |
51+ | Test Methods | camelCase verb | ` instanceForDifferentLevel() ` |
5552
5653### Null Safety
5754
58- - Every package has ` @NullMarked ` (jspecify) in its ` package-info.java `
59- - Use ` @Nullable ` from ` org.jspecify.annotations ` (NOT ` javax.annotation ` )
60- - All types are non-null by default; annotate nullable params/returns/fields explicitly
55+ Every package has ` @NullMarked ` in ` package-info.java ` . Use ` @Nullable ` from ` org.jspecify.annotations ` (NOT ` javax.annotation ` ).
6156
6257### Annotations
6358
64- - ** Lombok** : ` @Value ` (immutable classes) , ` @Getter ` , ` @Builder ` , ` @EqualsAndHashCode(onlyExplicitlyIncluded = true) ` , ` @ToString `
59+ - ** Lombok** : ` @Value ` , ` @Getter ` , ` @Builder ` , ` @EqualsAndHashCode(onlyExplicitlyIncluded = true) `
6560- ** jspecify** : ` @NullMarked ` (package-level), ` @Nullable ` (per-element)
6661- ** Thread safety** : ` @ThreadSafe ` from ` javax.annotation.concurrent `
67- - ** JSON** : ` @CompiledJson ` from DSL-JSON for compile-time serialization
68- - Lombok and DSL-JSON are annotation-processed at compile time
62+ - ** JSON** : ` @CompiledJson ` from DSL-JSON
6963
70- ### Records and Immutability
64+ ### Records & Immutability
7165
72- - Use records for immutable data carriers: ` LogEvent ` , ` ConfigurationProperties ` , ` LoggerThresholdLevels ` , etc.
73- - Records commonly implement interfaces (e.g., ` TimestampPattern implements RenderingPattern ` )
74- - Use Lombok ` @Value ` for immutable classes that need more than record semantics
66+ Use records for immutable data carriers. Use Lombok ` @Value ` for immutable classes needing more than record semantics.
7567
7668### Design Patterns
7769
78- - ** Interface-based design ** : ` LogHandler ` , ` LogEventWriter ` , ` RenderingPattern ` , ` PerformanceSensitive `
79- - ** Enum singletons** : ` NativeLogServiceManager.INSTANCE ` for lifecycle management
80- - ** Private constructors** on utility classes: ` StackTraces ` , ` ElementPatterns `
70+ - Interface-based: ` LogHandler ` , ` LogEventWriter ` , ` RenderingPattern `
71+ - Enum singletons: ` NativeLogServiceManager.INSTANCE `
72+ - Private constructors on utility classes
8173
8274### Error Handling
8375
84- - Wrap checked exceptions in unchecked: ` UncheckedIOException ` for IO errors
85- - Use ` IllegalArgumentException ` for invalid configuration/inputs
86- - Use ` assert ` for internal invariants
87- - Avoid checked exceptions in public APIs
88- - Internal logging uses ` elf4j.util.UtilLogger ` (e.g., ` UtilLogger.WARN.log(...) ` )
76+ Wrap checked exceptions in unchecked (` UncheckedIOException ` ). Use ` IllegalArgumentException ` for invalid config/inputs. Use ` assert ` for internal invariants. Internal logging uses ` elf4j.util.UtilLogger ` .
8977
9078### Thread Safety
9179
92- - Logger instances are thread-safe (usable as static/instance/local variables)
93- - Annotate with ` @ThreadSafe ` from ` javax.annotation.concurrent `
94- - Use ` ReentrantLock ` instead of ` synchronized ` (virtual-thread friendly)
95- - Prefer immutable records and ` @Value ` classes
96-
97- ### Javadoc
98-
99- - Use ` /** */ ` for public API documentation; ` /* */ ` for implementation details
100- - Javadoc formatting is enforced by Spotless
80+ Logger instances are thread-safe. Use ` @ThreadSafe ` annotation. Use ` ReentrantLock ` instead of ` synchronized ` .
10181
10282## Testing
10383
104- - ** JUnit 5** (Jupiter) with ` @Test ` , ` @Nested ` , ` @ParameterizedTest ` , ` @ValueSource `
105- - ** Mockito** with BDD style: ` given() ` , ` then() ` , ` willReturn() ` , ` should() `
106- - ** JUnit assertions** for most tests: ` assertEquals ` , ` assertNotNull ` , ` assertThrows ` , etc.
107- - ** AssertJ** available for fluent assertions
108- - ** Spring ` ReflectionTestUtils ` ** for injecting mocks into Lombok ` @Value ` classes
84+ - ** JUnit 5** : ` @Test ` , ` @Nested ` , ` @ParameterizedTest ` , ` @ValueSource `
85+ - ** Mockito** : BDD style with ` given() ` , ` then() ` , ` willReturn() ` , ` should() `
86+ - ** AssertJ** : Available for fluent assertions
87+ - ** Spring ` ReflectionTestUtils ` ** : For injecting mocks into Lombok ` @Value ` classes
10988
11089### Test Conventions
11190
112- - Test classes are ** package-private** (no ` public ` modifier)
113- - Use ` @ExtendWith(MockitoExtension.class) ` for Mockito integration
114- - Group related tests with ` @Nested ` inner classes named after the method under test
115- - Use ` @Mock ` for field-level mocks, ` mock() ` for local/inline mocks
116- - Mockito uses ` mock-maker-inline ` (configured in test resources)
117- - A custom ` TestExecutionListener ` adds a 2-second delay after tests for async log flushing
118-
119- ### Test Example Pattern
91+ - Test classes are ** package-private** (no ` public ` )
92+ - Use ` @ExtendWith(MockitoExtension.class) `
93+ - Group tests with ` @Nested ` classes named after the method under test
94+ - Use ` @Mock ` for field mocks, ` mock() ` for inline mocks
95+ - Tests have a 2-second delay after completion for async log flushing
12096
12197``` java
12298@ExtendWith (MockitoExtension . class)
@@ -139,31 +115,29 @@ class FooTest {
139115
140116```
141117src/main/java/elf4j/engine/
142- NativeLogger.java # Core Logger (implements elf4j API)
143- NativeLoggerFactory.java # SPI LoggerFactory entry point
118+ NativeLogger.java # Core Logger (implements elf4j API)
119+ NativeLoggerFactory.java # SPI LoggerFactory entry point
144120 logging/
145- LogEvent.java # Record: log event data
146- EventingLogHandler.java # Async log handler
147- NativeLogServiceManager.java # Enum singleton: lifecycle
148- configuration/ # Config loading & logger thresholds
149- pattern/element/ # Log output patterns (timestamp, JSON, etc. )
150- writer/ # stdout/stderr writers
151- util/ # Stack trace utilities
152- src/test/java/elf4j/engine/ # Mirrors main structure
121+ LogEvent.java # Record: log event data
122+ EventingLogHandler.java # Async log handler
123+ NativeLogServiceManager.java # Enum singleton: lifecycle
124+ configuration/ # Config loading & logger thresholds
125+ pattern/element/ # Log output patterns (timestamp, JSON)
126+ writer/ # stdout/stderr writers
127+ util/ # Stack trace utilities
128+ src/test/java/elf4j/engine/ # Mirrors main structure
153129src/test/resources/
154- elf4j-test.properties # Test log configuration
130+ elf4j-test.properties # Test log configuration
155131```
156132
157133## Key Dependencies
158134
159- | Dependency | Purpose |
160- | -------------| ----------------------------------------------|
161- | elf4j | ELF4J logging API (this engine implements it) |
162- | Lombok | ` @Value ` , ` @Builder ` , ` @Getter ` , code gen |
163- | jspecify | ` @NullMarked ` , ` @Nullable ` null safety |
164- | DSL-JSON | Compile-time JSON serialization (` @CompiledJson ` ) |
165- | conseq4j | Sequenced concurrent async execution |
166- | Guava | General utilities |
167- | SLF4J | MDC adapter integration |
168- | JUnit 5 | Test framework |
169- | Mockito | Mocking (BDD style) |
135+ | Dependency | Purpose |
136+ | ------------| ---------|
137+ | elf4j | ELF4J logging API (this engine implements) |
138+ | Lombok | ` @Value ` , ` @Builder ` , ` @Getter ` , code gen |
139+ | jspecify | ` @NullMarked ` , ` @Nullable ` null safety |
140+ | DSL-JSON | Compile-time JSON (` @CompiledJson ` ) |
141+ | conseq4j | Sequenced concurrent async execution |
142+ | JUnit 5 | Test framework |
143+ | Mockito | Mocking (BDD style) |
0 commit comments