log: http better log handling

This commit is contained in:
Tigor Hutasuhut 2024-04-29 12:27:46 +07:00
parent 66fc1a964b
commit 2f66122be1
8 changed files with 100 additions and 26 deletions

View file

@ -7,6 +7,7 @@ import (
"net/http" "net/http"
"time" "time"
"github.com/tigorlazuardi/redmage/pkg/caller"
"github.com/tigorlazuardi/redmage/pkg/errs" "github.com/tigorlazuardi/redmage/pkg/errs"
) )
@ -22,6 +23,8 @@ func (reddit *Reddit) CheckSubreddit(ctx context.Context, params CheckSubredditP
ctx, span := tracer.Start(ctx, "*Reddit.CheckSubreddit") ctx, span := tracer.Start(ctx, "*Reddit.CheckSubreddit")
defer span.End() defer span.End()
ctx = caller.WithContext(ctx, caller.New(2))
url := fmt.Sprintf("https://reddit.com/%s/%s.json?limit=1", params.SubredditType, params.Subreddit) url := fmt.Sprintf("https://reddit.com/%s/%s.json?limit=1", params.SubredditType, params.Subreddit)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, http.NoBody) req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, http.NoBody)
if err != nil { if err != nil {

View file

@ -4,6 +4,7 @@ import (
"net/http" "net/http"
"github.com/tigorlazuardi/redmage/config" "github.com/tigorlazuardi/redmage/config"
"github.com/tigorlazuardi/redmage/pkg/log"
) )
type Client interface { type Client interface {
@ -25,6 +26,22 @@ func (ro roundTripperFunc) RoundTrip(req *http.Request) (*http.Response, error)
func createRoundTripper(cfg *config.Config) roundTripperFunc { func createRoundTripper(cfg *config.Config) roundTripperFunc {
return func(r *http.Request) (*http.Response, error) { return func(r *http.Request) (*http.Response, error) {
r.Header.Set("User-Agent", cfg.String("download.useragent")) r.Header.Set("User-Agent", cfg.String("download.useragent"))
return http.DefaultTransport.RoundTrip(r) resp, err := http.DefaultTransport.RoundTrip(r)
if err != nil {
log.New(r.Context()).
Err(err).
Errorf("reddit: %s %s", r.Method, r.URL)
return resp, err
}
if resp.StatusCode >= 400 {
log.New(r.Context()).
Errorf("reddit: %s %s %d", r.Method, r.URL, resp.StatusCode)
return resp, err
}
if resp.StatusCode >= 200 && resp.StatusCode < 300 {
log.New(r.Context()).
Infof("reddit: %s %s %d", r.Method, r.URL, resp.StatusCode)
}
return resp, err
} }
} }

View file

@ -1,6 +1,7 @@
package caller package caller
import ( import (
"context"
"log/slog" "log/slog"
"os" "os"
"runtime" "runtime"
@ -70,3 +71,14 @@ func From(pc uintptr) Caller {
c.Frame, _ = runtime.CallersFrames([]uintptr{pc}).Next() c.Frame, _ = runtime.CallersFrames([]uintptr{pc}).Next()
return c return c
} }
type contextKey struct{}
func WithContext(ctx context.Context, caller Caller) context.Context {
return context.WithValue(ctx, contextKey{}, caller)
}
func FromContext(ctx context.Context) (Caller, bool) {
call, ok := ctx.Value(contextKey{}).(Caller)
return call, ok
}

View file

@ -273,6 +273,9 @@ func (entry *Entry) getCaller() caller.Caller {
if entry.caller.PC != 0 { if entry.caller.PC != 0 {
return entry.caller return entry.caller
} }
if call, ok := caller.FromContext(entry.ctx); ok {
return call
}
return caller.New(4) return caller.New(4)
} }

View file

@ -2,7 +2,7 @@ POST http://localhost:8080/api/v1/subreddits HTTP/1.1
Host: localhost:8080 Host: localhost:8080
{ {
"name": "CultureImpact", "name": "AnimeLandscapes",
"enable_schedule": 1, "enable_schedule": 1,
"schedule": "@daily", "schedule": "@daily",
"countback": 300 "countback": 300

View file

@ -3,5 +3,5 @@ Host: localhost:8080
Content-Type: application/json Content-Type: application/json
{ {
"subreddit": "CultureImpact" "subreddit": "AnimeLandscapes"
} }

View file

@ -24,11 +24,11 @@ templ home(_ *views.Context, data Data) {
<div class="prose"> <div class="prose">
<section class="mb-4 mx-auto"> <section class="mb-4 mx-auto">
<h1>Recently Added</h1> <h1>Recently Added</h1>
for _, deviceMapValue := range data.RecentlyAddedImages { for _, recently := range data.RecentlyAddedImages {
<h2>{ deviceMapValue.device.Name }</h2> <h2>{ recently.Device.Name }</h2>
for _, subreddit := range deviceMapValue.subreddits { for _, subreddit := range recently.Subreddits {
<h4>{ subreddit.subreddit.Name }</h4> <h4>{ subreddit.Subreddit.Name }</h4>
@RecentlyAddedImageList(subreddit.images, 0) @RecentlyAddedImageList(subreddit.Images, 0)
} }
} }
</section> </section>

View file

@ -1,6 +1,9 @@
package homeview package homeview
import ( import (
"slices"
"strings"
"github.com/tigorlazuardi/redmage/api" "github.com/tigorlazuardi/redmage/api"
"github.com/tigorlazuardi/redmage/models" "github.com/tigorlazuardi/redmage/models"
) )
@ -11,38 +14,74 @@ type Data struct {
Error error Error error
} }
type RecentlyAddedImages = map[int32]deviceMapValue type RecentlyAddedImages = []RecentlyAddedImage
type deviceMapValue struct {
device *models.Device
subreddits map[int32]subredditMapValue
}
type subredditMapValue struct { type subredditMapValue struct {
subreddit *models.Subreddit subreddit *models.Subreddit
images []*models.Image images []*models.Image
} }
type RecentlyAddedImage struct {
Device *models.Device
Subreddits []Subreddit
}
type Subreddit struct {
Subreddit *models.Subreddit
Images models.ImageSlice
}
func NewRecentlyAddedImages(images models.ImageSlice) RecentlyAddedImages { func NewRecentlyAddedImages(images models.ImageSlice) RecentlyAddedImages {
r := make(RecentlyAddedImages) r := make(RecentlyAddedImages, 0, len(images))
for _, image := range images { for _, image := range images {
if image.R.Device == nil || image.R.Subreddit == nil { if image.R.Device == nil || image.R.Subreddit == nil {
continue continue
} }
if _, ok := r[image.R.Device.ID]; !ok { var deviceFound bool
r[image.R.Device.ID] = deviceMapValue{ for i, ra := range r {
device: image.R.Device, if ra.Device.ID == image.R.Device.ID {
subreddits: make(map[int32]subredditMapValue), deviceFound = true
var subredditFound bool
for j, subreddit := range r[i].Subreddits {
if subreddit.Subreddit.ID == image.R.Subreddit.ID {
subredditFound = true
r[i].Subreddits[j].Images = append(r[i].Subreddits[j].Images, image)
}
}
if !subredditFound {
r[i].Subreddits = append(r[i].Subreddits, Subreddit{
Subreddit: image.R.Subreddit,
Images: models.ImageSlice{image},
})
}
} }
} }
if _, ok := r[image.R.Device.ID].subreddits[image.R.Subreddit.ID]; !ok { if !deviceFound {
r[image.R.Device.ID].subreddits[image.R.Subreddit.ID] = subredditMapValue{} r = append(r, RecentlyAddedImage{
} Device: image.R.Device,
images := append(r[image.R.Device.ID].subreddits[image.R.Subreddit.ID].images, image) Subreddits: []Subreddit{
r[image.R.Device.ID].subreddits[image.R.Subreddit.ID] = subredditMapValue{ {
subreddit: image.R.Subreddit, Subreddit: image.R.Subreddit,
images: images, Images: models.ImageSlice{image},
},
},
})
} }
} }
for _, r := range r {
slices.SortFunc(r.Subreddits, func(left, right Subreddit) int {
leftName := strings.ToLower(left.Subreddit.Name)
rightName := strings.ToLower(right.Subreddit.Name)
return strings.Compare(leftName, rightName)
})
}
slices.SortFunc(r, func(left, right RecentlyAddedImage) int {
leftName := strings.ToLower(left.Device.Name)
rightName := strings.ToLower(right.Device.Name)
return strings.Compare(leftName, rightName)
})
return r return r
} }