Skip to content

Commit

Permalink
Updated docs, added changelog.
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewlalis committed Jan 27, 2024
1 parent 30fc5b1 commit 1d09eb3
Show file tree
Hide file tree
Showing 7 changed files with 31 additions and 25 deletions.
32 changes: 17 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,14 +90,14 @@ logger.warn("A message");

### Configuring the Provider

By default, SLF4D uses a built-in logging provider that simply writes log messages to stdout and stderr. However, if you'd like to use a third-party logging provider instead, or create your own custom provider, all you need to do is call `configureLoggingProvider()` when your application starts, to set the shared logging provider to use.
By default, SLF4D uses a built-in logging provider that simply writes log messages to stdout and stderr. However, if you'd like to use a third-party logging provider instead, or create your own custom provider, all you need to do is call `configureLoggingProvider()` when your application starts, to set the logging provider to use.

```d
import slf4d;
import some_slf4d_provider;
void main() {
configureLoggingProvider(new shared CustomProvider());
configureLoggingProvider(new CustomProvider());
info("This message is handled by the custom provider!");
}
```
Expand Down Expand Up @@ -127,29 +127,31 @@ Here's an example.
```d
unittest {
import slf4d;
shared TestingLoggingProvider provider = getTestingProvider();
import slf4d.test;
callMySystemUnderTest();
withTestingProvider((provider) {
callMySystemUnderTest();
provider.assertMessageCount(3);
provider.assertHasMessage("Hello world!");
assert(provider.messages[0].level == Levels.INFO);
assert(provider.messages[1].message == "Hello world!");
provider.assertMessageCount(3);
provider.assertHasMessage("Hello world!");
assert(provider.messages[0].level == Levels.INFO);
assert(provider.messages[1].message == "Hello world!");
// Reset the testing provider to clear all log messages.
provider.reset();
// Reset the testing provider to clear all log messages.
provider.reset();
callMyOtherSystemUnderTest();
callMyOtherSystemUnderTest();
// Check that there are no warn/error messages.
provider.assertNoMessages(Levels.WARN);
provider.assertNoMessages(Levels.ERROR);
// Check that there are no warn/error messages.
provider.assertNoMessages(Levels.WARN);
provider.assertNoMessages(Levels.ERROR);
});
}
```

## Making a Custom Provider

To create a logging provider, simply implement the `LoggingProvider` interface defined in `slf4d.provider`. Note that your logging factory and handler should be `shared`, that is, they will be shared among all threads of an application which uses your provider. Consider using a mutex or `synchronized` in your handler or factory if it needs to access a shared resource.
To create a logging provider, simply implement the `LoggingProvider` interface defined in `slf4d.provider`. Consider using a mutex or `synchronized` in your handler or factory if it needs to access a shared resource.

Check out [examples/custom-provider](https://github.com/andrewlalis/slf4d/tree/main/examples/custom-provider) for an example of how you can create such a logging provider.

Expand Down
4 changes: 4 additions & 0 deletions changelogs/3.0.0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Version 3.0.0
- Removed all usage of the D language `shared` attribute.
- Added testing function `withTestingProvider` to run some code with a fresh TestingLoggingProvider instance.
- Added testing function `withTestingLock` to run some code while having a lock on the global testing logging state.
2 changes: 1 addition & 1 deletion docs/src/guide/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import my_lib;
void main() {
// In this example, we'll just be using SLF4D's default logging provider
// but you can use any SLF4D provider.
auto provider = new shared DefaultProvider(true, Levels.DEBUG, "log-files");
auto provider = new DefaultProvider(true, Levels.DEBUG, "log-files");
configureLoggingProvider(provider);
myComplexFunction(42);
Expand Down
6 changes: 3 additions & 3 deletions docs/src/guide/configuring.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

In SLF4D, all log messages generated throughout your application are handled by a [LoggingProvider](ddoc-slf4d.provider.LoggingProvider). The LoggingProvider is responsible for providing a [LoggerFactory](ddoc-slf4d.factory.LoggerFactory) that creates the [Logger](ddoc-slf4d.logger.Logger) components you use when you call a log function.

By default, SLF4D is initialized with its own built-in [DefaultProvider](ddoc-slf4d.default_provider.provider.DefaultProvider) that forwards all log messages to stdout or stderr. However, you can configure a different provider by calling [configureLoggingProvider](ddoc-slf4d.configureLoggingProvider) and passing in the provider you want to use. Note that your provider should be `shared`.
By default, SLF4D is initialized with its own built-in [DefaultProvider](ddoc-slf4d.default_provider.provider.DefaultProvider) that forwards all log messages to stdout or stderr. However, you can configure a different provider by calling [configureLoggingProvider](ddoc-slf4d.configureLoggingProvider) and passing in the provider you want to use.

Here's an example where we configure SLF4D to use the DefaultProvider, but we turn off console colors and set the root logging level to TRACE:

Expand All @@ -11,11 +11,11 @@ import slf4d;
import slf4d.default_provider;
void main() {
auto provider = new shared DefaultProvider(false, Levels.TRACE);
auto provider = new DefaultProvider(false, Levels.TRACE);
configureLoggingProvider(provider);
info("Application started!");
}
```

**`configureLoggingProvider` should only be called once on application startup!** Calling this function at any other point in your program can lead to undefined behavior. Library developers should _never_ call this function, besides in unit tests.
> ⚠️ **`configureLoggingProvider` should only be called once on application startup!** Calling this function at any other point in your program can lead to undefined behavior. Library developers should _never_ call this function, besides in unit tests.
2 changes: 1 addition & 1 deletion docs/src/guide/default-provider.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import slf4d;
import slf4d.default_provider;
void main() {
auto provider = new shared DefaultProvider(
auto provider = new DefaultProvider(
true, // Enable colored output using ANSI color codes.
Levels.DEBUG, // Only log messages that are DEBUG or higher (so no TRACE).
"log-files" // Also write log messages to files in the "log-files" dir.
Expand Down
9 changes: 4 additions & 5 deletions docs/src/guide/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,10 @@ string getFileContents(string filename) {
unittest {
import slf4d.test;
synchronized(loggingTestingMutex) {
auto testingProvider = getTestingProvider();
withTestingProvider((provider) {
assert(getFileContents("missing-file") == "");
assert(testingProvider.messageCount == 1);
assert(testingProivder.messages[0].level == Levels.WARN);
}
assert(provider.messageCount == 1);
assert(proivder.messages[0].level == Levels.WARN);
});
}
```
1 change: 1 addition & 0 deletions source/slf4d/test.d
Original file line number Diff line number Diff line change
Expand Up @@ -83,5 +83,6 @@ public void withTestingLock(void delegate() dg) {
public void withTestingProvider(void delegate(TestingLoggingProvider) dg) {
acquireLoggingTestingLock();
dg(getTestingProvider());
resetLoggingState();
releaseLoggingTestingLock();
}

0 comments on commit 1d09eb3

Please sign in to comment.