Skip to content

Commit

Permalink
Merge pull request #95 from itishrishikesh/slog_json_out
Browse files Browse the repository at this point in the history
NewClientWithJSONSlogger
  • Loading branch information
vaibhav-kaushal authored Nov 7, 2023
2 parents 4e7daa7 + 796332c commit 06e8282
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 17 deletions.
49 changes: 39 additions & 10 deletions client/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## IMPORTANT: It is not Yet Built

## What does the client do?
## What does the client do?
The Bark client (just _client_ henceforth) is the _library_ side of the bark. It is the piece that takes in the logs from any golang program and sends it to the server which is configured against the client. It is supposed to have the utility functions to help users log to bark directly from go code without having to worry about network calls and such.

## Levels of Logs
Expand All @@ -19,7 +19,7 @@ The client defines 7 levels of logs:
Any single character in the place of error level in a parsable single log message would indicate the level of **INFO**.

## Simple usecase
The client can be initialized and used as follows (we explain the options below code sample):
The client can be initialized and used as follows (we explain the options below code sample):

```go
barkClient := client.NewClient("<bark_server_url>", "<default_log_level>", "<default_service_name>", "<service_instance_name>",
Expand All @@ -41,12 +41,12 @@ The options that are used for initializing the client are as follows:
- **bark_server_url**: This is the URL of a running bark server. It must end in `/`. For example `http://bark.example.com/` or `http://127.0.0.1:8080/`
- **default_log_level**: When you use `Println` or `Default`, the log message is parsed (rules for prasing are described [here](../_nocode/docs/log-string-parsing-in-bark.md)) and if it does not contain any indication for what the log level is, then the value supplied in this field is used as the log level for sent log message. When using dedicated methods for error levels (e.g. `Panic`, `Error` etc.), the parsed error level is overwritten.
- **default_service_name**: This is the name of the service which is sending the log - so it has to be the name of the program or service which is calling it. In case a blank string is sent, the value against `constants.DefaultLogServiceName` (currently set to `def_svc`) is used.
- **service_instance_name**: This is the name of the calling app's session. This value is supposed to indicate which instance among possibly multiple instances of a service sent a log message. For example, in case of the service being deployed within Kubernetes, it might indicate the service's pod's name. If the value is sent as a blank string, client will try to use the machine's hostname. If it fails to fetch the hostname, a random string will be used instead.
- **service_instance_name**: This is the name of the calling app's instance. This value is supposed to indicate which instance among possibly multiple instances of a service sent a log message. For example, in case of the service being deployed within Kubernetes, it might indicate the service's pod's name. If the value is sent as a blank string, client will try to use the machine's hostname. If it fails to fetch the hostname, a random string will be used instead.
- **enable_slog**: This enables [slog](https://go.dev/blog/slog) for the client. When this option is enabled, all logs in addition to being sent to the bark server is also printed on STDOUT of the service.
- **enable_bulk_dispatch**: Setting this to true would enable the client to push all the requests being received in a channel and start using it. It improves the overall performance of the client sending log entries to the server.

### Simplest usecase (without any server)
The simplest usecase of any logging library is to print to STDOUT. While the primary usecase of bark is to be able to dispatch log messages to a remote server, when we start off with a new project, we often just want to start logging things to STDOUT. Maybe even later, that is how we want to use logs. For such usecases, the client library offers `NewSloggerClient` which uses the built in [slog](https://go.dev/blog/slog) package in go (version 1.21+) to log your messages to STDOUT with levels. Example:
The simplest usecase of any logging library is to print to STDOUT. While the primary usecase of bark is to be able to dispatch log messages to a remote server, when we start off with a new project, we often just want to start logging things to STDOUT. Maybe even later, that is how we want to use logs. For such usecases, the client library offers `NewSloggerClient` which uses the built in [slog](https://go.dev/blog/slog) package in go (version 1.21+) to log your messages to STDOUT with levels. Example:

```go
log := client.NewSloggerClient("INFO")
Expand All @@ -60,7 +60,7 @@ log.Info("Info message")
log.Debug("Debug message")
log.Println("Println message")
```
The above piece of code will end up printing something like the following (the dates in the beginning of each line will vary):
The above piece of code will end up printing something like the following (the dates in the beginning of each line will vary):

```
2023/10/15 21:57:41 PANIC Panic message
Expand All @@ -73,8 +73,37 @@ The above piece of code will end up printing something like the following (the d
2023/10/15 21:57:41 INFO Println message
```

### Printing logs in JSON format
If you just want the logs to be printed in JSON format you can use `NewSloggerClientJson` method from a client as shown below,


```go
log := client.NewSloggerClientJson(constants.Info)
log.Info("1N09FW - This is an Info message!")
log.Debug("1N09GG - This is an Debug message!")
log.Warn("1N09H5 - This is an Warn message!")
log.Notice("1N09HL - This is an Notice message!")
log.Error("1N09HT - This is an Error message!")
log.Panic("1N09I7 - This is an Panic message!")
log.Alert("1N09IG - This is an Alert message!", false)
log.Default("I#1N09JH - This is an Default message!")
log.Println("D#1N09JR - This is an Print message!")
```
The above piece of code will end up printing something like the following (the dates in the beginning of each line will vary):
```
{"time":"2023-11-04T20:35:35.0472358+05:30","level":"INFO","msg":"1N09FW - This is an Info message!"}
{"time":"2023-11-04T20:35:35.0510558+05:30","level":"DEBUG","msg":"1N09GG - This is an Debug message!"}
{"time":"2023-11-04T20:35:35.0572919+05:30","level":"WARN","msg":"1N09H5 - This is an Warn message!"}
{"time":"2023-11-04T20:35:35.0578286+05:30","level":"NOTICE","msg":"1N09HL - This is an Notice message!"}
{"time":"2023-11-04T20:35:35.0580332+05:30","level":"ERROR","msg":"1N09HT - This is an Error message!"}
{"time":"2023-11-04T20:35:35.0586284+05:30","level":"PANIC","msg":"1N09I7 - This is an Panic message!"}
{"time":"2023-11-04T20:35:35.0586284+05:30","level":"ALERT","msg":"1N09IG - This is an Alert message!"}
{"time":"2023-11-04T20:35:35.0591469+05:30","level":"INFO","msg":"I#1N09JH - This is an Default message!"}
{"time":"2023-11-04T20:35:35.059302+05:30","level":"DEBUG","msg":"D#1N09JR - This is an Default message!"}
```

## Printing logs to a file
Bark client, as shown above, is capable of sending logs to a server as well as printing them to the standard output as well. It can also do both of those things simultaneously. The architecture in very simple representation looks like this:
Bark client, as shown above, is capable of sending logs to a server as well as printing them to the standard output as well. It can also do both of those things simultaneously. The architecture in very simple representation looks like this:

![barkslogger.svg](../_nocode/images/barkslogger.svg)

Expand All @@ -100,7 +129,7 @@ The above code will write the output to `random.txt` file. You can expect the fi
2023/10/18 19:27:51 INFO Some Message that'll be sent to random.txt file
```

### Slog and writing to a file
### Slog and writing to a file

Bark client uses [slog](https://go.dev/blog/slog) internally to handle the printing of the logs. Slog is a simple and structured logging library that comes with Go (version 1.21+).

Expand Down Expand Up @@ -131,9 +160,9 @@ func main() {

// We are using JSONHandler here so the line that will be logged will actually be a JSON string
log.SetSlogHandler(slog.NewJSONHandler(file, client.SlogHandlerOptions()))

// If you want to log to STDOUT, you can use `os.Stdout` in place of the `file` as writer
// Of course in case that you would have remove the unused code from above.

// Of course in case that you would have removed the unused code from above.
log.Info("Some Message that'll be sent to random.txt file")
log.WaitAndEnd()
}
Expand All @@ -153,7 +182,7 @@ If you add a nil options, the log labels will appear as described in the [slog d
> LevelDebug Level = -4 \
> LevelInfo Level = 0 \
> LevelWarn Level = 4 \
> LevelError Level = 8 \
> LevelError Level = 8
The custom log levels defined by bark client have the following values:

Expand Down
9 changes: 9 additions & 0 deletions client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -675,6 +675,15 @@ func NewClientWithServer(dbUrl, defaultLogLvl, svcName, svcInstName string, enab
}
}

// NewSloggerClientJson returns a Config object that will print logs to stdout in JSON format.
// *Config returned by NewSloggerClientJson behaves the same as NewSloggerClient, but it prints the logs in JSON.
// NewClientWithJSONSlogger accepts the same parameters as NewSloggerClient.
func NewSloggerClientJson(defaultLogLvl string) *Config {
client := NewSloggerClient(defaultLogLvl)
client.SetSlogHandler(slog.NewJSONHandler(os.Stdout, SlogHandlerOptions()))
return client
}

// SetCustomOut allows users to set output to custom writer instead of the default standard output
func (c *Config) SetCustomOut(out io.Writer) {
c.Slogger = newSlogger(out)
Expand Down
19 changes: 19 additions & 0 deletions cmd/examples/client_json_slogger/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package main

import (
"github.com/techrail/bark/client"
"github.com/techrail/bark/constants"
)

func main() {
log := client.NewSloggerClientJson(constants.Info)
log.Info("1N09FW - This is an Info message!")
log.Debug("1N09GG - This is an Debug message!")
log.Warn("1N09H5 - This is an Warn message!")
log.Notice("1N09HL - This is an Notice message!")
log.Error("1N09HT - This is an Error message!")
log.Panic("1N09I7 - This is an Panic message!")
log.Alert("1N09IG - This is an Alert message!", false)
log.Default("I#1N09JH - This is an Default message!")
log.Println("D#1N09JR - This is an Print message!")
}
14 changes: 7 additions & 7 deletions cmd/examples/client_wait/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,13 +66,13 @@ func main() {
log.Println("1LPWC7 - Default message")

_ = log.Raw(client.RawLog{
LogTime: time.Now().UTC(),
LogLevel: "INFO",
ServiceName: "Bark Test",
SessionName: "TestSessionWait1",
Code: "1M2U4J",
Message: "Testing raw log",
MoreData: nil,
LogTime: time.Now().UTC(),
LogLevel: "INFO",
ServiceName: "Bark Test",
ServiceInstanceName: "TestSessionWait1",
Code: "1M2U4J",
Message: "Testing raw log",
MoreData: nil,
}, false)

log.WaitAndEnd()
Expand Down

0 comments on commit 06e8282

Please sign in to comment.