Skip to content

Commit bc09676

Browse files
committed
Add context information to logger with logrus
1 parent 4d0bcee commit bc09676

File tree

8 files changed

+104
-12
lines changed

8 files changed

+104
-12
lines changed

cmd/gopherapi/main.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package main
33
import (
44
"flag"
55
"fmt"
6-
"log"
76
"net/http"
87
"os"
98
"strconv"
@@ -12,6 +11,8 @@ import (
1211
gopher "github.com/friendsofgo/gopherapi/pkg"
1312
"github.com/friendsofgo/gopherapi/pkg/adding"
1413
"github.com/friendsofgo/gopherapi/pkg/fetching"
14+
"github.com/friendsofgo/gopherapi/pkg/log"
15+
"github.com/friendsofgo/gopherapi/pkg/log/hooks"
1516
"github.com/friendsofgo/gopherapi/pkg/modifying"
1617
"github.com/friendsofgo/gopherapi/pkg/removing"
1718
"github.com/friendsofgo/gopherapi/pkg/server"
@@ -40,8 +41,10 @@ func main() {
4041
gophers = sample.Gophers
4142
}
4243

44+
logger := log.NewLogger(hooks.NewServerInformationHook())
45+
4346
repo := inmem.NewRepository(gophers)
44-
fetchingService := fetching.NewService(repo)
47+
fetchingService := fetching.NewService(repo, logger)
4548
addingService := adding.NewService(repo)
4649
modifyingService := modifying.NewService(repo)
4750
removingService := removing.NewService(repo)
@@ -58,5 +61,5 @@ func main() {
5861
)
5962

6063
fmt.Println("The gopher server is on tap now:", httpAddr)
61-
log.Fatal(http.ListenAndServe(httpAddr, s.Router()))
64+
logger.Fatal(http.ListenAndServe(httpAddr, s.Router()))
6265
}

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ module github.com/friendsofgo/gopherapi
33
require (
44
github.com/gorilla/mux v1.7.0
55
github.com/joho/godotenv v1.3.0
6+
github.com/sirupsen/logrus v1.4.2
67
)

go.sum

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,13 @@
1+
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
12
github.com/gorilla/mux v1.7.0 h1:tOSd0UKHQd6urX6ApfOn4XdBMY6Sh1MfxV3kmaazO+U=
23
github.com/gorilla/mux v1.7.0/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
34
github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc=
45
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
6+
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
7+
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
8+
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
9+
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
10+
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
11+
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
12+
golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc=
13+
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=

pkg/fetching/service.go

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,23 @@ import (
44
"context"
55

66
gopher "github.com/friendsofgo/gopherapi/pkg"
7+
"github.com/friendsofgo/gopherapi/pkg/log"
78
)
89

910
// Service provides fetching operations.
1011
type Service interface {
1112
FetchGophers(ctx context.Context) ([]gopher.Gopher, error)
12-
FetchGopherByID(ctx context.Context, ID string) (*gopher.Gopher, error)
13+
FetchGopherByID(ctx context.Context, ID string) *gopher.Gopher
1314
}
1415

1516
type service struct {
1617
repository gopher.Repository
18+
logger *log.Logger
1719
}
1820

1921
// NewService creates a fetching service with the necessary dependencies
20-
func NewService(repository gopher.Repository) Service {
21-
return &service{repository}
22+
func NewService(repository gopher.Repository, logger *log.Logger) Service {
23+
return &service{repository, logger}
2224
}
2325

2426
// FetchGophers returns all gophers
@@ -27,6 +29,14 @@ func (s *service) FetchGophers(ctx context.Context) ([]gopher.Gopher, error) {
2729
}
2830

2931
// FetchGopherByID returns a gopher
30-
func (s *service) FetchGopherByID(ctx context.Context, ID string) (*gopher.Gopher, error) {
31-
return s.repository.FetchGopherByID(ctx, ID)
32+
func (s *service) FetchGopherByID(ctx context.Context, ID string) *gopher.Gopher {
33+
g, err := s.repository.FetchGopherByID(ctx, ID)
34+
35+
// This error can be any error type of our repository
36+
if err != nil {
37+
s.logger.UnexpectedError(ctx, err)
38+
return nil
39+
}
40+
41+
return g
3242
}

pkg/log/hooks/server.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package hooks
2+
3+
import (
4+
"github.com/sirupsen/logrus"
5+
6+
"github.com/friendsofgo/gopherapi/pkg/server"
7+
)
8+
9+
type serverHook struct{}
10+
11+
func NewServerInformationHook() logrus.Hook {
12+
return &serverHook{}
13+
}
14+
15+
func (h *serverHook) Fire(entry *logrus.Entry) error {
16+
ctx := entry.Context
17+
18+
hostname, _ := server.Name(ctx)
19+
httpAddr, _ := server.HttpAddr(ctx)
20+
21+
entry.Data["hostname"] = hostname
22+
entry.Data["httpAddr"] = httpAddr
23+
24+
return nil
25+
}
26+
27+
func (h *serverHook) Levels() []logrus.Level {
28+
return logrus.AllLevels
29+
}

pkg/log/logger.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package log
2+
3+
import (
4+
"context"
5+
6+
"github.com/sirupsen/logrus"
7+
)
8+
9+
// Event stores messages to log later, from our standard interface
10+
type Event struct {
11+
id string
12+
message string
13+
}
14+
15+
// Logger centralize log messages format
16+
type Logger struct {
17+
*logrus.Logger
18+
}
19+
20+
// NewLogger initializes the standard logger
21+
func NewLogger(hooks ...logrus.Hook) *Logger {
22+
logger := logrus.New()
23+
24+
for _, hook := range hooks {
25+
logger.AddHook(hook)
26+
}
27+
28+
return &Logger{logger}
29+
}
30+
31+
// Declare variables to store log messages as new Events
32+
var (
33+
unexpectedErrorMessage = Event{"01DK2XFX9PQ85ZPZ5CP68P108Y", "Unexpected error: %v"}
34+
)
35+
36+
// ElementNotFound is a standard error message for elements not found
37+
func (l *Logger) UnexpectedError(ctx context.Context, err error) {
38+
l.WithContext(ctx).WithField("logid", unexpectedErrorMessage.id).
39+
Errorf(unexpectedErrorMessage.message, err)
40+
}

pkg/server/server.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,10 +93,10 @@ func (s *server) FetchGopher(w http.ResponseWriter, r *http.Request) {
9393
ctx := s.createContext(r.Context())
9494

9595
vars := mux.Vars(r)
96-
gopher, err := s.fetching.FetchGopherByID(ctx, vars["ID"])
96+
gopher := s.fetching.FetchGopherByID(ctx, vars["ID"])
9797
w.Header().Set("Content-Type", "application/json")
98-
if err != nil {
99-
w.WriteHeader(http.StatusNotFound) // We use not found for simplicity
98+
if gopher == nil {
99+
w.WriteHeader(http.StatusNotFound)
100100
_ = json.NewEncoder(w).Encode("Gopher Not found")
101101
return
102102
}

pkg/storage/inmem/repository.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ func (r *gopherRepository) FetchGopherByID(ctx context.Context, ID string) (*gop
6969
}
7070
}
7171

72-
return nil, fmt.Errorf("The ID %s doesn't exist", ID)
72+
return nil, fmt.Errorf("Error has ocurred while finding gopher %s", ID)
7373
}
7474

7575
func (r *gopherRepository) checkIfExists(ctx context.Context, ID string) error {

0 commit comments

Comments
 (0)