diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index db8eb2a5..99c0b26c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -86,6 +86,8 @@ jobs: with: context: "{{defaultContext}}:cyclops-ctrl" platforms: linux/amd64,linux/arm64 + build-args: | + VERSION=${{ github.event.inputs.version }} push: true tags: cyclopsui/cyclops-ctrl:${{ github.event.inputs.version }} diff --git a/cyclops-ctrl/.env b/cyclops-ctrl/.env index 45d4f4d0..c5c171ed 100644 --- a/cyclops-ctrl/.env +++ b/cyclops-ctrl/.env @@ -1,3 +1,4 @@ -DISABLE_TELEMETRY=true +DISABLE_TELEMETRY=false PORT=8888 -WATCH_NAMESPACE=cyclops \ No newline at end of file +WATCH_NAMESPACE=cyclops +CYCLOPS_VERSION=v0.0.0 diff --git a/cyclops-ctrl/Dockerfile b/cyclops-ctrl/Dockerfile index 92e7eba4..d6b84a59 100644 --- a/cyclops-ctrl/Dockerfile +++ b/cyclops-ctrl/Dockerfile @@ -13,6 +13,9 @@ RUN go build -o /build/bin ./... FROM alpine:3.20.0 +ARG VERSION +ENV CYCLOPS_VERSION=$VERSION + WORKDIR /app RUN mkdir /app/bin diff --git a/cyclops-ctrl/cmd/main/main.go b/cyclops-ctrl/cmd/main/main.go index 196cc416..1c8a0fbd 100644 --- a/cyclops-ctrl/cmd/main/main.go +++ b/cyclops-ctrl/cmd/main/main.go @@ -63,7 +63,11 @@ func main() { setupLog.Info("starting handler") - telemetryClient, _ := telemetry.NewClient(getEnvBool("DISABLE_TELEMETRY"), setupLog) + telemetryClient, _ := telemetry.NewClient( + getEnvBool("DISABLE_TELEMETRY"), + os.Getenv("CYCLOPS_VERSION"), + setupLog, + ) telemetryClient.InstanceStart() k8sClient, err := k8sclient.New() diff --git a/cyclops-ctrl/internal/controller/templates.go b/cyclops-ctrl/internal/controller/templates.go index aef080b5..94688af0 100644 --- a/cyclops-ctrl/internal/controller/templates.go +++ b/cyclops-ctrl/internal/controller/templates.go @@ -12,21 +12,25 @@ import ( "github.com/cyclops-ui/cyclops/cyclops-ctrl/internal/cluster/k8sclient" "github.com/cyclops-ui/cyclops/cyclops-ctrl/internal/mapper" "github.com/cyclops-ui/cyclops/cyclops-ctrl/internal/models/dto" + "github.com/cyclops-ui/cyclops/cyclops-ctrl/internal/telemetry" "github.com/cyclops-ui/cyclops/cyclops-ctrl/internal/template" ) type Templates struct { templatesRepo *template.Repo kubernetesClient *k8sclient.KubernetesClient + telemetryClient telemetry.Client } func NewTemplatesController( templatesRepo *template.Repo, kubernetes *k8sclient.KubernetesClient, + telemetryClient telemetry.Client, ) *Templates { return &Templates{ templatesRepo: templatesRepo, kubernetesClient: kubernetes, + telemetryClient: telemetryClient, } } @@ -136,6 +140,8 @@ func (c *Templates) CreateTemplatesStore(ctx *gin.Context) { k8sTemplateStore := mapper.DTOToTemplateStore(*templateStore, tmpl.IconURL) + c.telemetryClient.TemplateCreation() + if err := c.kubernetesClient.CreateTemplateStore(k8sTemplateStore); err != nil { ctx.JSON(http.StatusInternalServerError, dto.NewError("Error creating module", err.Error())) return @@ -174,6 +180,8 @@ func (c *Templates) EditTemplatesStore(ctx *gin.Context) { k8sTemplateStore := mapper.DTOToTemplateStore(*templateStore, tmpl.IconURL) + c.telemetryClient.TemplateEdit() + if err := c.kubernetesClient.UpdateTemplateStore(k8sTemplateStore); err != nil { ctx.JSON(http.StatusInternalServerError, dto.NewError("Error creating module", err.Error())) return diff --git a/cyclops-ctrl/internal/handler/handler.go b/cyclops-ctrl/internal/handler/handler.go index 44ddd5d1..391feb64 100644 --- a/cyclops-ctrl/internal/handler/handler.go +++ b/cyclops-ctrl/internal/handler/handler.go @@ -44,7 +44,7 @@ func New( func (h *Handler) Start() error { gin.SetMode(gin.DebugMode) - templatesController := controller.NewTemplatesController(h.templatesRepo, h.k8sClient) + templatesController := controller.NewTemplatesController(h.templatesRepo, h.k8sClient, h.telemetryClient) modulesController := controller.NewModulesController(h.templatesRepo, h.k8sClient, h.renderer, h.telemetryClient, h.monitor) clusterController := controller.NewClusterController(h.k8sClient) diff --git a/cyclops-ctrl/internal/telemetry/client.go b/cyclops-ctrl/internal/telemetry/client.go index 86c561ca..f29b1cfd 100644 --- a/cyclops-ctrl/internal/telemetry/client.go +++ b/cyclops-ctrl/internal/telemetry/client.go @@ -9,6 +9,8 @@ type Client interface { ModuleCreation() ModuleReconciliation() InstanceStart() + TemplateCreation() + TemplateEdit() } type logger interface { @@ -19,11 +21,12 @@ type logger interface { type EnqueueClient struct { client posthog.Client distinctID string + version string } type MockClient struct{} -func NewClient(disable bool, logger logger) (Client, error) { +func NewClient(disable bool, version string, logger logger) (Client, error) { if disable { logger.Info("telemetry disabled") return MockClient{}, nil @@ -53,6 +56,7 @@ func NewClient(disable bool, logger logger) (Client, error) { return EnqueueClient{ client: client, distinctID: idStr, + version: version, }, nil } @@ -60,6 +64,9 @@ func (c EnqueueClient) InstanceStart() { _ = c.client.Enqueue(posthog.Capture{ Event: "cyclops-instance-start", DistinctId: c.distinctID, + Properties: map[string]interface{}{ + "version": c.version, + }, }) } @@ -67,6 +74,9 @@ func (c EnqueueClient) ModuleReconciliation() { _ = c.client.Enqueue(posthog.Capture{ Event: "module-reconciliation", DistinctId: c.distinctID, + Properties: map[string]interface{}{ + "version": c.version, + }, }) } @@ -74,9 +84,34 @@ func (c EnqueueClient) ModuleCreation() { _ = c.client.Enqueue(posthog.Capture{ Event: "module-creation", DistinctId: c.distinctID, + Properties: map[string]interface{}{ + "version": c.version, + }, + }) +} + +func (c EnqueueClient) TemplateCreation() { + _ = c.client.Enqueue(posthog.Capture{ + Event: "template-creation", + DistinctId: c.distinctID, + Properties: map[string]interface{}{ + "version": c.version, + }, }) } +func (c EnqueueClient) TemplateEdit() { + _ = c.client.Enqueue(posthog.Capture{ + Event: "template-edit", + DistinctId: c.distinctID, + Properties: map[string]interface{}{ + "version": c.version, + }, + }) +} + +// region mock client + func (c MockClient) InstanceStart() { } @@ -85,3 +120,9 @@ func (c MockClient) ModuleReconciliation() { func (c MockClient) ModuleCreation() { } + +func (c MockClient) TemplateCreation() {} + +func (c MockClient) TemplateEdit() {} + +// endregion diff --git a/web/docs/usage_metrics/usage_metrics.md b/web/docs/usage_metrics/usage_metrics.md index ea526249..c4dc636a 100644 --- a/web/docs/usage_metrics/usage_metrics.md +++ b/web/docs/usage_metrics/usage_metrics.md @@ -6,7 +6,10 @@ These events include: **- `cyclops-instance-start`** - triggered once at the start of cyclops-ctrl pod **- `module-creation`** - called by the UI each time you create a new module -**- `module-reconciliation`** - each time a Module CRD in the cluster is changed +**- `module-reconciliation`** - each time a Module CRD in the cluster is changed +**- `template-creation`** - called each time a template is added in the `Templates` tab +**- `template-edit`** - called each time a template is edited in the `Templates` tab + The metric collection is implemented using [posthog](https://posthog.com). @@ -17,12 +20,16 @@ Each time one of the events above is triggered, Cyclops sends an HTTP request to "type": "capture", "timestamp": "2024-03-23T19:05:38.808279+01:00", "distinct_id": "f46d57f0-e93f-11ee-924c-8281c5d92ae4", - "event": "cyclops-instance-start" + "event": "cyclops-instance-start", + "properties": { + "version": "v0.10.0" + } } ``` `distinct_id` - generated for each Cyclops instance using [NewUUID](https://pkg.go.dev/github.com/google/uuid#NewUUID) from google/uuid package -`event` - which event was triggered; see events above +`event` - which event was triggered; see events above +`properties.version` - version of your Cyclops instance ## Turn off