1
0
mirror of https://github.com/amir20/dozzle.git synced 2025-12-24 22:39:18 +01:00

feat: improves analytics by removing google analytics in favor of a simple ping (#2515)

This commit is contained in:
Amir Raminfar
2023-11-18 19:35:24 -08:00
committed by GitHub
parent 58fef4e16a
commit c659f103f8
4 changed files with 76 additions and 19 deletions

View File

@@ -31,11 +31,9 @@ declare global {
const controlledRef: typeof import('@vueuse/core')['controlledRef']
const createApp: typeof import('vue')['createApp']
const createEventHook: typeof import('@vueuse/core')['createEventHook']
const createGenericProjection: typeof import('@vueuse/math')['createGenericProjection']
const createGlobalState: typeof import('@vueuse/core')['createGlobalState']
const createInjectionState: typeof import('@vueuse/core')['createInjectionState']
const createPinia: typeof import('pinia')['createPinia']
const createProjection: typeof import('@vueuse/math')['createProjection']
const createReactiveFn: typeof import('@vueuse/core')['createReactiveFn']
const createReusableTemplate: typeof import('@vueuse/core')['createReusableTemplate']
const createSharedComposable: typeof import('@vueuse/core')['createSharedComposable']
@@ -70,9 +68,6 @@ declare global {
const isReadonly: typeof import('vue')['isReadonly']
const isRef: typeof import('vue')['isRef']
const lightTheme: typeof import('./stores/settings')['lightTheme']
const logicAnd: typeof import('@vueuse/math')['logicAnd']
const logicNot: typeof import('@vueuse/math')['logicNot']
const logicOr: typeof import('@vueuse/math')['logicOr']
const makeDestructurable: typeof import('@vueuse/core')['makeDestructurable']
const mapActions: typeof import('pinia')['mapActions']
const mapGetters: typeof import('pinia')['mapGetters']
@@ -120,7 +115,6 @@ declare global {
const refDefault: typeof import('@vueuse/core')['refDefault']
const refThrottled: typeof import('@vueuse/core')['refThrottled']
const refWithControl: typeof import('@vueuse/core')['refWithControl']
const releases: typeof import('./stores/releases')['default']
const resolveComponent: typeof import('vue')['resolveComponent']
const resolveRef: typeof import('@vueuse/core')['resolveRef']
const resolveUnref: typeof import('@vueuse/core')['resolveUnref']
@@ -160,7 +154,6 @@ declare global {
const unref: typeof import('vue')['unref']
const unrefElement: typeof import('@vueuse/core')['unrefElement']
const until: typeof import('@vueuse/core')['until']
const useAbs: typeof import('@vueuse/math')['useAbs']
const useActiveElement: typeof import('@vueuse/core')['useActiveElement']
const useAnimate: typeof import('@vueuse/core')['useAnimate']
const useArrayDifference: typeof import('@vueuse/core')['useArrayDifference']
@@ -178,7 +171,6 @@ declare global {
const useAsyncQueue: typeof import('@vueuse/core')['useAsyncQueue']
const useAsyncState: typeof import('@vueuse/core')['useAsyncState']
const useAttrs: typeof import('vue')['useAttrs']
const useAverage: typeof import('@vueuse/math')['useAverage']
const useBase64: typeof import('@vueuse/core')['useBase64']
const useBattery: typeof import('@vueuse/core')['useBattery']
const useBluetooth: typeof import('@vueuse/core')['useBluetooth']
@@ -186,8 +178,6 @@ declare global {
const useBroadcastChannel: typeof import('@vueuse/core')['useBroadcastChannel']
const useBrowserLocation: typeof import('@vueuse/core')['useBrowserLocation']
const useCached: typeof import('@vueuse/core')['useCached']
const useCeil: typeof import('@vueuse/math')['useCeil']
const useClamp: typeof import('@vueuse/math')['useClamp']
const useClipboard: typeof import('@vueuse/core')['useClipboard']
const useClipboardItems: typeof import('@vueuse/core')['useClipboardItems']
const useCloned: typeof import('@vueuse/core')['useCloned']
@@ -228,7 +218,6 @@ declare global {
const useFetch: typeof import('@vueuse/core')['useFetch']
const useFileDialog: typeof import('@vueuse/core')['useFileDialog']
const useFileSystemAccess: typeof import('@vueuse/core')['useFileSystemAccess']
const useFloor: typeof import('@vueuse/math')['useFloor']
const useFocus: typeof import('@vueuse/core')['useFocus']
const useFocusWithin: typeof import('@vueuse/core')['useFocusWithin']
const useFps: typeof import('@vueuse/core')['useFps']
@@ -250,13 +239,10 @@ declare global {
const useLogStream: typeof import('./composable/eventsource')['useLogStream']
const useMagicKeys: typeof import('@vueuse/core')['useMagicKeys']
const useManualRefHistory: typeof import('@vueuse/core')['useManualRefHistory']
const useMath: typeof import('@vueuse/math')['useMath']
const useMax: typeof import('@vueuse/math')['useMax']
const useMediaControls: typeof import('@vueuse/core')['useMediaControls']
const useMediaQuery: typeof import('@vueuse/core')['useMediaQuery']
const useMemoize: typeof import('@vueuse/core')['useMemoize']
const useMemory: typeof import('@vueuse/core')['useMemory']
const useMin: typeof import('@vueuse/math')['useMin']
const useMounted: typeof import('@vueuse/core')['useMounted']
const useMouse: typeof import('@vueuse/core')['useMouse']
const useMouseInElement: typeof import('@vueuse/core')['useMouseInElement']
@@ -276,19 +262,16 @@ declare global {
const usePointer: typeof import('@vueuse/core')['usePointer']
const usePointerLock: typeof import('@vueuse/core')['usePointerLock']
const usePointerSwipe: typeof import('@vueuse/core')['usePointerSwipe']
const usePrecision: typeof import('@vueuse/math')['usePrecision']
const usePreferredColorScheme: typeof import('@vueuse/core')['usePreferredColorScheme']
const usePreferredContrast: typeof import('@vueuse/core')['usePreferredContrast']
const usePreferredDark: typeof import('@vueuse/core')['usePreferredDark']
const usePreferredLanguages: typeof import('@vueuse/core')['usePreferredLanguages']
const usePreferredReducedMotion: typeof import('@vueuse/core')['usePreferredReducedMotion']
const usePrevious: typeof import('@vueuse/core')['usePrevious']
const useProjection: typeof import('@vueuse/math')['useProjection']
const useRafFn: typeof import('@vueuse/core')['useRafFn']
const useRefHistory: typeof import('@vueuse/core')['useRefHistory']
const useReleases: typeof import('./stores/releases')['useReleases']
const useResizeObserver: typeof import('@vueuse/core')['useResizeObserver']
const useRound: typeof import('@vueuse/math')['useRound']
const useRoute: typeof import('vue-router')['useRoute']
const useRouter: typeof import('vue-router')['useRouter']
const useScreenOrientation: typeof import('@vueuse/core')['useScreenOrientation']
@@ -308,7 +291,6 @@ declare global {
const useStorage: typeof import('@vueuse/core')['useStorage']
const useStorageAsync: typeof import('@vueuse/core')['useStorageAsync']
const useStyleTag: typeof import('@vueuse/core')['useStyleTag']
const useSum: typeof import('@vueuse/math')['useSum']
const useSupported: typeof import('@vueuse/core')['useSupported']
const useSwipe: typeof import('@vueuse/core')['useSwipe']
const useTemplateRefsList: typeof import('@vueuse/core')['useTemplateRefsList']
@@ -329,7 +311,6 @@ declare global {
const useToast: typeof import('./composable/toast')['useToast']
const useToggle: typeof import('@vueuse/core')['useToggle']
const useTransition: typeof import('@vueuse/core')['useTransition']
const useTrunc: typeof import('@vueuse/math')['useTrunc']
const useUrlSearchParams: typeof import('@vueuse/core')['useUrlSearchParams']
const useUserMedia: typeof import('@vueuse/core')['useUserMedia']
const useVModel: typeof import('@vueuse/core')['useVModel']

View File

@@ -0,0 +1,40 @@
package analytics
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"net/http/httputil"
log "github.com/sirupsen/logrus"
)
func SendBeacon(e BeaconEvent) error {
jsonValue, err := json.Marshal(e)
if err != nil {
return err
}
req, err := http.NewRequest("POST", "https://b.dozzle.dev/event", bytes.NewBuffer(jsonValue))
if err != nil {
return err
}
response, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer response.Body.Close()
if response.StatusCode/100 != 2 {
dump, err := httputil.DumpResponse(response, true)
if err != nil {
return err
}
log.Debugf("%v", string(dump))
return fmt.Errorf("google analytics returned non-2xx status code: %v", response.Status)
}
return nil
}

View File

@@ -16,3 +16,16 @@ type RequestEvent struct {
TotalContainers int `json:"totalContainers"`
RunningContainers int `json:"runningContainers"`
}
type BeaconEvent struct {
Version string `json:"version"`
Browser string `json:"browser"`
AuthProvider string `json:"authProvider"`
FilterLength int `json:"filterLength"`
RemoteHostLength int `json:"remoteHostLength"`
HasDocumentation bool `json:"hasDocumentation"`
HasCustomAddress bool `json:"hasCustomAddress"`
HasCustomBase bool `json:"hasCustomBase"`
HasHostname bool `json:"hasHostname"`
RunningContainers int `json:"runningContainers"`
}

View File

@@ -8,6 +8,8 @@ import (
"net/http"
"sync"
"github.com/amir20/dozzle/internal/analytics"
"github.com/amir20/dozzle/internal/content"
"github.com/amir20/dozzle/internal/docker"
log "github.com/sirupsen/logrus"
@@ -31,6 +33,18 @@ func (h *handler) streamEvents(w http.ResponseWriter, r *http.Request) {
events := make(chan docker.ContainerEvent)
stats := make(chan docker.ContainerStat)
pages, _ := content.ReadAll()
b := analytics.BeaconEvent{
Version: h.config.Version,
Browser: r.Header.Get("User-Agent"),
AuthProvider: string(h.config.Authorization.Provider),
HasHostname: h.config.Hostname != "",
HasCustomBase: h.config.Base != "",
HasCustomAddress: h.config.Addr != "",
RemoteHostLength: len(h.clients),
HasDocumentation: len(pages) > 0,
}
{
wg := sync.WaitGroup{}
wg.Add(len(h.clients))
@@ -69,9 +83,18 @@ func (h *handler) streamEvents(w http.ResponseWriter, r *http.Request) {
log.Errorf("error writing containers to event stream: %v", err)
}
b.RunningContainers = len(allContainers)
f.Flush()
}
if !h.config.NoAnalytics {
go func() {
if err := analytics.SendBeacon(b); err != nil {
log.Debugf("error sending beacon: %v", err)
}
}()
}
for {
select {
case stat := <-stats: