Skip to content

Instantly share code, notes, and snippets.

@dimiro1
Created July 21, 2023 21:00
Show Gist options
  • Save dimiro1/a99ab1df79ad2547731cf13d667b07c8 to your computer and use it in GitHub Desktop.
Save dimiro1/a99ab1df79ad2547731cf13d667b07c8 to your computer and use it in GitHub Desktop.
package main
import (
"log"
"time"
)
// User is a user in the application.
type User struct {
ID int
Name string
}
// UsersRepository an abstraction for a repository of users.
type UsersRepository interface {
// GetUserByID returns a user by its ID.
GetUserByID(id int) (User, error)
}
// SimpleUsersRepository is a simple implementation of UsersRepository.
type SimpleUsersRepository struct{}
// GetUserByID returns a user by its ID.
// of course, this is a dummy implementation.
func (s SimpleUsersRepository) GetUserByID(id int) (User, error) {
return User{ID: id, Name: "John"}, nil
}
// InstrumentedUsersRepository is a wrapper for UsersRepository that adds instrumentation.
type InstrumentedUsersRepository struct {
repo UsersRepository
}
// GetUserByID calls the underlying repository while adding basic instrumentation.
func (i InstrumentedUsersRepository) GetUserByID(id int) (User, error) {
start := time.Now()
// Here we can add any logic we want, for example, logging, metrics, etc.
// In this example we are just logging the call, but we could start a new span using the open-telemetry, NewRelic, DataDog etc.
log.Printf("start calling GetUserByID with id %d", id)
user, err := i.repo.GetUserByID(id)
log.Printf("finished calling GetUserByID with id %d, took: %d", id, time.Since(start))
return user, err
}
func main() {
var repo UsersRepository
// Create a new instance of the simple repository.
repo = SimpleUsersRepository{}
// Wrap the simple repository with the instrumented one.
repo = InstrumentedUsersRepository{repo: repo}
// Call the instrumented repository.
user, err := repo.GetUserByID(1)
log.Println(user, err)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment