Compare commits

...

5 Commits

Author SHA1 Message Date
e93c7ec5c0 Update go-app
All checks were successful
Build and Publish / release (push) Successful in 6m10s
2025-01-12 20:22:56 -05:00
c2bde1e1dd Update TODO 2025-01-12 19:27:10 -05:00
44bf293eab Proxy observability updates
All checks were successful
Build and Publish / release (push) Successful in 2m51s
2025-01-12 19:14:24 -05:00
f87b35b306 Perform proxy updates in goroutines 2025-01-12 19:10:30 -05:00
eaf2cf211d Update wunderground url
All checks were successful
Build and Publish / release (push) Successful in 2m36s
2025-01-12 19:06:45 -05:00
7 changed files with 57 additions and 26 deletions

View File

@ -2,10 +2,12 @@
- [ ] Helm Chart
- [ ] Update README
- [ ] Add Grafana dashboard
- [ ] Add proxy to upstream support
- [ ] Add new spans
## Done
- [x] Add proxy to upstream support
- [x] Fix wunderground 401
- [x] Perform proxy calls in goroutines
- [x] Configuration for app
- [x] Configurable metric prefix
- [x] Add device name field with ID/Key mappings

2
go.mod
View File

@ -3,7 +3,7 @@ module gitea.libretechconsulting.com/rmcguire/ambient-weather-local-exporter
go 1.23.4
require (
gitea.libretechconsulting.com/rmcguire/go-app v0.3.1
gitea.libretechconsulting.com/rmcguire/go-app v0.3.2
github.com/go-resty/resty/v2 v2.16.3
github.com/gorilla/schema v1.4.1
github.com/rs/zerolog v1.33.0

4
go.sum
View File

@ -1,5 +1,5 @@
gitea.libretechconsulting.com/rmcguire/go-app v0.3.1 h1:jydcJ+Vv8sk+Le7nTI2+b6E7FfV+ShBJo7YdxmdaCYc=
gitea.libretechconsulting.com/rmcguire/go-app v0.3.1/go.mod h1:wHOWh4O4AMDATQ3WEUYjq5a5bnICPBpu5G6BsNxqN38=
gitea.libretechconsulting.com/rmcguire/go-app v0.3.2 h1:zAT6wmEEODYWx+iU3adlmFNW4FCTHzRvIepFIOQZGjk=
gitea.libretechconsulting.com/rmcguire/go-app v0.3.2/go.mod h1:ug6g+FyEi2LguWTQfd+bZrTd1ECsot8BylxgMFEO5DM=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/caarlos0/env/v11 v11.3.1 h1:cArPWC15hWmEt+gWk7YBi7lEXTXCvpaSdCiZE2X5mCA=

View File

@ -7,6 +7,7 @@ import (
"context"
"fmt"
"net/http"
"sync"
"gitea.libretechconsulting.com/rmcguire/go-app/pkg/otel"
"github.com/rs/zerolog"
@ -120,26 +121,40 @@ func (aw *AmbientWeather) handleProviderRequest(
// Uses a weather update to allow awn to publish to wunderground and
// visa versa.
if station := update.StationConfig; station != nil {
// Perform proxy updates in parallel if enabled
var proxyWg sync.WaitGroup
if station.ProxyToAWN {
err := aw.awnProvider.ProxyReq(ctx, update)
if err != nil {
zerolog.Ctx(aw.appCtx).Err(err).Msg("failed to proxy to ambient weather")
return
}
zerolog.Ctx(aw.appCtx).Debug().
Str("station", station.Name).
Msg("proxied weather update to awn")
proxyWg.Add(1)
go func() {
defer proxyWg.Done()
err := aw.awnProvider.ProxyReq(ctx, update)
if err != nil {
zerolog.Ctx(aw.appCtx).Err(err).Msg("failed to proxy to ambient weather")
return
}
zerolog.Ctx(aw.appCtx).Debug().
Str("station", station.Name).
Msg("proxied weather update to awn")
}()
}
if station.ProxyToWunderground {
err := aw.wuProvider.ProxyReq(ctx, update)
if err != nil {
zerolog.Ctx(aw.appCtx).Err(err).Msg("failed to proxy to ambient weather")
return
}
zerolog.Ctx(aw.appCtx).Debug().
Str("station", station.Name).
Msg("proxied weather update to wunderground")
proxyWg.Add(1)
go func() {
defer proxyWg.Done()
err := aw.wuProvider.ProxyReq(ctx, update)
if err != nil {
zerolog.Ctx(aw.appCtx).Err(err).Msg("failed to proxy to ambient weather")
return
}
zerolog.Ctx(aw.appCtx).Debug().
Str("station", station.Name).
Msg("proxied weather update to wunderground")
}()
}
proxyWg.Wait()
}
}

View File

@ -8,6 +8,7 @@ import (
"gitea.libretechconsulting.com/rmcguire/go-app/pkg/otel"
"github.com/go-resty/resty/v2"
"github.com/rs/zerolog/log"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/codes"
@ -43,12 +44,18 @@ func (awn *AWNProvider) ProxyReq(ctx context.Context, update *weather.WeatherUpd
Get(awnURL)
if err != nil {
span.RecordError(err)
span.SetAttributes(
attribute.String("query", resp.Request.QueryParam.Encode()),
attribute.String("body", string(resp.Body())),
)
span.SetStatus(codes.Error, err.Error())
log.Err(err).Any("query", resp.Request.PathParams).
Int("statusCode", resp.StatusCode()).
Msg("awn proxy failed")
}
span.SetAttributes(
attribute.Int("statusCode", resp.StatusCode()),
attribute.String("body", string(resp.Body())),
)
return err

View File

@ -15,7 +15,7 @@ type WUProvider struct{}
const (
providerName = "weatherunderground"
wuURL = "http://rtupdate.wunderground.com/weatherstation/updateweatherstation.php"
wuURL = "https://rtupdate.wunderground.com/weatherstation/updateweatherstation.php"
)
func (wu *WUProvider) Name() string {

View File

@ -4,9 +4,9 @@ import (
"context"
"errors"
"net/url"
"time"
"github.com/go-resty/resty/v2"
"github.com/rs/zerolog/log"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/codes"
"k8s.io/utils/ptr"
@ -39,12 +39,19 @@ func (wu *WUProvider) ProxyReq(ctx context.Context, update *weather.WeatherUpdat
Get(wuURL)
if err != nil {
span.SetStatus(codes.Error, err.Error())
span.SetAttributes(
attribute.String("query", resp.Request.QueryParam.Encode()),
attribute.String("body", string(resp.Body())),
)
span.RecordError(err)
log.Err(err).
Int("statusCode", resp.StatusCode()).
Any("query", resp.Request.PathParams).
Msg("wunderground proxy failed")
}
span.SetAttributes(
attribute.Int("statusCode", resp.StatusCode()),
attribute.String("body", string(resp.Body())),
)
return err
@ -52,11 +59,11 @@ func (wu *WUProvider) ProxyReq(ctx context.Context, update *weather.WeatherUpdat
func updateToWuParams(u *weather.WeatherUpdate) *url.Values {
params := &url.Values{}
params.Set("dateutc", time.Now().Format(time.DateTime))
weather.SetURLVal(params, "ID", &u.StationConfig.WundergroundID)
weather.SetURLVal(params, "PASSWORD", &u.StationConfig.WundergroundPassword)
params.Set("action", "updateraw")
params.Set("dateutc", "now")
weather.SetURLVal(params, "UV", u.UV)
weather.SetURLVal(params, "action", ptr.To("updateraw"))
weather.SetURLVal(params, "baromin", u.BaromRelativeIn)
weather.SetURLVal(params, "dailyrainin", u.DailyRainIn)
weather.SetURLVal(params, "dewptf", u.DewPointF)