Skip to content

Commit f9af5a8

Browse files
snehith57624nishant
andauthored
fix: [1122][EA]send installation event to posthog (#1200)
* send installation event to posthog * send installation event to posthog configmap * dev config * commited wire for ea * telemetry client for EA(base class) * telemetry event client changes * updating install event key value * Update App.go * Update App.go * Update PosthogClient.go * Update PosthogClient.go * Update TelemetryEventClient.go * telemetry event client changes as per PR comments * telemetry event client changes as per PR comments * telemetry event client changes as per PR comments * telemetry event client changes as per PR comments * merging with main * updating as per PR comments * updating as per PR comments * updating as per PR comments * updating as per PR comments Co-authored-by: nishant <[email protected]>
1 parent 762a282 commit f9af5a8

File tree

7 files changed

+336
-117
lines changed

7 files changed

+336
-117
lines changed

client/telemetry/TelemetryEventClient.go

Lines changed: 89 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@ import (
44
"encoding/base64"
55
"encoding/json"
66
"fmt"
7-
"github.com/devtron-labs/devtron/internal/sql/repository"
8-
"github.com/devtron-labs/devtron/internal/sql/repository/pipelineConfig"
7+
"github.com/devtron-labs/devtron/api/bean"
98
util2 "github.com/devtron-labs/devtron/internal/util"
109
"github.com/devtron-labs/devtron/pkg/cluster"
1110
"github.com/devtron-labs/devtron/pkg/user"
@@ -20,34 +19,30 @@ import (
2019
"google.golang.org/grpc/status"
2120
"k8s.io/api/core/v1"
2221
v12 "k8s.io/apimachinery/pkg/apis/meta/v1"
22+
"k8s.io/apimachinery/pkg/version"
2323
"net/http"
2424
"time"
2525
)
2626

2727
type TelemetryEventClientImpl struct {
28-
cron *cron.Cron
29-
logger *zap.SugaredLogger
30-
client *http.Client
31-
clusterService cluster.ClusterService
32-
K8sUtil *util2.K8sUtil
33-
aCDAuthConfig *util3.ACDAuthConfig
34-
environmentService cluster.EnvironmentService
35-
userService user.UserService
36-
appListingRepository repository.AppListingRepository
37-
PosthogClient *PosthogClient
38-
ciPipelineRepository pipelineConfig.CiPipelineRepository
39-
pipelineRepository pipelineConfig.PipelineRepository
28+
cron *cron.Cron
29+
logger *zap.SugaredLogger
30+
client *http.Client
31+
clusterService cluster.ClusterService
32+
K8sUtil *util2.K8sUtil
33+
aCDAuthConfig *util3.ACDAuthConfig
34+
userService user.UserService
35+
PosthogClient *PosthogClient
4036
}
4137

4238
type TelemetryEventClient interface {
4339
GetTelemetryMetaInfo() (*TelemetryMetaInfo, error)
40+
SendTelemtryInstallEventEA() (*TelemetryEventType, error)
4441
}
4542

4643
func NewTelemetryEventClientImpl(logger *zap.SugaredLogger, client *http.Client, clusterService cluster.ClusterService,
47-
K8sUtil *util2.K8sUtil, aCDAuthConfig *util3.ACDAuthConfig,
48-
environmentService cluster.EnvironmentService, userService user.UserService,
49-
appListingRepository repository.AppListingRepository, PosthogClient *PosthogClient,
50-
ciPipelineRepository pipelineConfig.CiPipelineRepository, pipelineRepository pipelineConfig.PipelineRepository) (*TelemetryEventClientImpl, error) {
44+
K8sUtil *util2.K8sUtil, aCDAuthConfig *util3.ACDAuthConfig, userService user.UserService,
45+
PosthogClient *PosthogClient) (*TelemetryEventClientImpl, error) {
5146
cron := cron.New(
5247
cron.WithChain())
5348
cron.Start()
@@ -56,9 +51,7 @@ func NewTelemetryEventClientImpl(logger *zap.SugaredLogger, client *http.Client,
5651
logger: logger,
5752
client: client, clusterService: clusterService,
5853
K8sUtil: K8sUtil, aCDAuthConfig: aCDAuthConfig,
59-
environmentService: environmentService, userService: userService,
60-
appListingRepository: appListingRepository, PosthogClient: PosthogClient,
61-
ciPipelineRepository: ciPipelineRepository, pipelineRepository: pipelineRepository,
54+
userService: userService, PosthogClient: PosthogClient,
6255
}
6356

6457
watcher.HeartbeatEventForTelemetry()
@@ -80,26 +73,19 @@ func (impl *TelemetryEventClientImpl) StopCron() {
8073
impl.cron.Stop()
8174
}
8275

83-
type TelemetryEventDto struct {
76+
type TelemetryEventEA struct {
8477
UCID string `json:"ucid"` //unique client id
8578
Timestamp time.Time `json:"timestamp"`
8679
EventMessage string `json:"eventMessage,omitempty"`
8780
EventType TelemetryEventType `json:"eventType"`
88-
Summary *SummaryDto `json:"summary,omitempty"`
81+
Summary *SummaryEA `json:"summary,omitempty"`
8982
ServerVersion string `json:"serverVersion,omitempty"`
9083
DevtronVersion string `json:"devtronVersion,omitempty"`
9184
}
9285

93-
type SummaryDto struct {
94-
ProdAppCount int `json:"prodAppCount,omitempty"`
95-
NonProdAppCount int `json:"nonProdAppCount,omitempty"`
96-
UserCount int `json:"userCount,omitempty"`
97-
EnvironmentCount int `json:"environmentCount,omitempty"`
98-
ClusterCount int `json:"clusterCount,omitempty"`
99-
CiCountPerDay int `json:"ciCountPerDay,omitempty"`
100-
CdCountPerDay int `json:"cdCountPerDay,omitempty"`
101-
HelmChartCount int `json:"helmChartCount,omitempty"`
102-
SecurityScanCountPerDay int `json:"securityScanCountPerDay,omitempty"`
86+
type SummaryEA struct {
87+
UserCount int `json:"userCount,omitempty"`
88+
ClusterCount int `json:"clusterCount,omitempty"`
10389
}
10490

10591
const DevtronUniqueClientIdConfigMap = "devtron-ucid"
@@ -124,82 +110,55 @@ const (
124110
InstallationApplicationError TelemetryEventType = "InstallationApplicationError"
125111
)
126112

127-
func (impl *TelemetryEventClientImpl) SummaryEventForTelemetry() {
128-
ucid, err := impl.getUCID()
129-
if err != nil {
130-
impl.logger.Errorw("exception caught inside telemetry summary event", "err", err)
131-
return
132-
}
133-
134-
if IsOptOut {
135-
impl.logger.Warnw("client is opt-out for telemetry, there will be no events capture", "ucid", ucid)
136-
return
137-
}
138-
113+
func (impl *TelemetryEventClientImpl) SummaryDetailsForTelemetry() (cluster []cluster.ClusterBean, user []bean.UserInfo, k8sServerVersion *version.Info) {
139114
discoveryClient, err := impl.K8sUtil.GetK8sDiscoveryClientInCluster()
140115
if err != nil {
141116
impl.logger.Errorw("exception caught inside telemetry summary event", "err", err)
142117
return
143118
}
144-
k8sServerVersion, err := discoveryClient.ServerVersion()
119+
k8sServerVersion, err = discoveryClient.ServerVersion()
145120
if err != nil {
146121
impl.logger.Errorw("exception caught inside telemetry summary event", "err", err)
147122
return
148123
}
149-
payload := &TelemetryEventDto{UCID: ucid, Timestamp: time.Now(), EventType: Summary, DevtronVersion: "v1"}
150-
payload.ServerVersion = k8sServerVersion.String()
151-
clusters, err := impl.clusterService.FindAllActive()
152-
if err != nil && err != pg.ErrNoRows {
153-
impl.logger.Errorw("exception caught inside telemetry summary event", "err", err)
154-
return
155-
}
156-
157-
environments, err := impl.environmentService.GetAllActive()
158-
if err != nil && err != pg.ErrNoRows {
159-
impl.logger.Errorw("exception caught inside telemetry summary event", "err", err)
160-
return
161-
}
162124

163125
users, err := impl.userService.GetAll()
164126
if err != nil && err != pg.ErrNoRows {
165127
impl.logger.Errorw("exception caught inside telemetry summery event", "err", err)
166128
return
167129
}
168130

169-
prodApps, err := impl.appListingRepository.FindAppCount(true)
131+
clusters, err := impl.clusterService.FindAllActive()
170132
if err != nil && err != pg.ErrNoRows {
171133
impl.logger.Errorw("exception caught inside telemetry summary event", "err", err)
172134
return
173135
}
136+
return clusters, users, k8sServerVersion
137+
}
174138

175-
nonProdApps, err := impl.appListingRepository.FindAppCount(false)
176-
if err != nil && err != pg.ErrNoRows {
139+
func (impl *TelemetryEventClientImpl) SummaryEventForTelemetry() {
140+
ucid, err := impl.getUCID()
141+
if err != nil {
177142
impl.logger.Errorw("exception caught inside telemetry summary event", "err", err)
178143
return
179144
}
180145

181-
ciPipeline, err := impl.ciPipelineRepository.FindAllPipelineInLast24Hour()
182-
if err != nil && err != pg.ErrNoRows {
183-
impl.logger.Errorw("exception caught inside telemetry summary event", "err", err)
146+
if IsOptOut {
147+
impl.logger.Warnw("client is opt-out for telemetry, there will be no events capture", "ucid", ucid)
184148
return
185149
}
186150

187-
cdPipeline, err := impl.pipelineRepository.FindAllPipelineInLast24Hour()
188-
if err != nil && err != pg.ErrNoRows {
189-
impl.logger.Errorw("exception caught inside telemetry summary event", "err", err)
190-
return
191-
}
151+
clusters, users, k8sServerVersion := impl.SummaryDetailsForTelemetry()
192152

193-
summery := &SummaryDto{
194-
ProdAppCount: prodApps,
195-
NonProdAppCount: nonProdApps,
196-
UserCount: len(users),
197-
EnvironmentCount: len(environments),
198-
ClusterCount: len(clusters),
199-
CiCountPerDay: len(ciPipeline),
200-
CdCountPerDay: len(cdPipeline),
153+
payload := &TelemetryEventEA{UCID: ucid, Timestamp: time.Now(), EventType: Summary, DevtronVersion: "v1"}
154+
payload.ServerVersion = k8sServerVersion.String()
155+
156+
summary := &SummaryEA{
157+
UserCount: len(users),
158+
ClusterCount: len(clusters),
201159
}
202-
payload.Summary = summery
160+
payload.Summary = summary
161+
203162
reqBody, err := json.Marshal(payload)
204163
if err != nil {
205164
impl.logger.Errorw("SummaryEventForTelemetry, payload marshal error", "error", err)
@@ -212,6 +171,13 @@ func (impl *TelemetryEventClientImpl) SummaryEventForTelemetry() {
212171
return
213172
}
214173

174+
err = impl.EnqueuePostHog(ucid, Summary, prop)
175+
if err != nil {
176+
impl.logger.Errorw("SummaryEventForTelemetry, failed to push event", "ucid", ucid, "error", err)
177+
}
178+
}
179+
180+
func (impl *TelemetryEventClientImpl) EnqueuePostHog(ucid string, eventType TelemetryEventType, prop map[string]interface{}) error {
215181
if impl.PosthogClient.Client == nil {
216182
impl.logger.Warn("no posthog client found, creating new")
217183
client, err := impl.retryPosthogClient(PosthogApiKey, PosthogEndpoint)
@@ -220,15 +186,17 @@ func (impl *TelemetryEventClientImpl) SummaryEventForTelemetry() {
220186
}
221187
}
222188
if impl.PosthogClient.Client != nil {
223-
err = impl.PosthogClient.Client.Enqueue(posthog.Capture{
189+
err := impl.PosthogClient.Client.Enqueue(posthog.Capture{
224190
DistinctId: ucid,
225-
Event: string(Summary),
191+
Event: string(eventType),
226192
Properties: prop,
227193
})
228194
if err != nil {
229195
impl.logger.Errorw("SummaryEventForTelemetry, failed to push event", "error", err)
196+
return err
230197
}
231198
}
199+
return nil
232200
}
233201

234202
func (impl *TelemetryEventClientImpl) HeartbeatEventForTelemetry() {
@@ -252,7 +220,7 @@ func (impl *TelemetryEventClientImpl) HeartbeatEventForTelemetry() {
252220
impl.logger.Errorw("exception caught inside telemetry heartbeat event", "err", err)
253221
return
254222
}
255-
payload := &TelemetryEventDto{UCID: ucid, Timestamp: time.Now(), EventType: Heartbeat, DevtronVersion: "v1"}
223+
payload := &TelemetryEventEA{UCID: ucid, Timestamp: time.Now(), EventType: Heartbeat, DevtronVersion: "v1"}
256224
payload.ServerVersion = k8sServerVersion.String()
257225
reqBody, err := json.Marshal(payload)
258226
if err != nil {
@@ -266,21 +234,12 @@ func (impl *TelemetryEventClientImpl) HeartbeatEventForTelemetry() {
266234
return
267235
}
268236

269-
if impl.PosthogClient.Client == nil {
270-
impl.logger.Warn("no posthog client found, creating new")
271-
client, err := impl.retryPosthogClient(PosthogApiKey, PosthogEndpoint)
272-
if err == nil {
273-
impl.PosthogClient.Client = client
274-
}
275-
}
276-
if impl.PosthogClient.Client != nil {
277-
err = impl.PosthogClient.Client.Enqueue(posthog.Capture{
278-
DistinctId: ucid,
279-
Event: string(Heartbeat),
280-
Properties: prop,
281-
})
237+
err = impl.EnqueuePostHog(ucid, Heartbeat, prop)
238+
if err == nil {
282239
if err != nil {
283-
impl.logger.Errorw("HeartbeatEventForTelemetry, failed to push event", "error", err)
240+
impl.logger.Warnw("HeartbeatEventForTelemetry, failed to push event", "error", err)
241+
} else {
242+
impl.logger.Debugw("HeartbeatEventForTelemetry success")
284243
}
285244
}
286245
}
@@ -299,6 +258,40 @@ func (impl *TelemetryEventClientImpl) GetTelemetryMetaInfo() (*TelemetryMetaInfo
299258
return data, err
300259
}
301260

261+
func (impl *TelemetryEventClientImpl) SendTelemtryInstallEventEA() (*TelemetryEventType, error) {
262+
ucid, err := impl.getUCID()
263+
if err != nil {
264+
impl.logger.Errorw("exception while getting unique client id", "error", err)
265+
return nil, err
266+
}
267+
268+
client, err := impl.K8sUtil.GetClientForInCluster()
269+
if err != nil {
270+
impl.logger.Errorw("exception while getting unique client id", "error", err)
271+
return nil, err
272+
}
273+
274+
cm, err := impl.K8sUtil.GetConfigMap(impl.aCDAuthConfig.ACDConfigMapNamespace, DevtronUniqueClientIdConfigMap, client)
275+
datamap := cm.Data
276+
277+
installEventValue, installEventKeyExists := datamap[InstallEventKey]
278+
279+
if installEventKeyExists == false || installEventValue == "1" {
280+
err = impl.EnqueuePostHog(ucid, InstallationSuccess, nil)
281+
if err == nil {
282+
datamap[InstallEventKey] = "2"
283+
cm.Data = datamap
284+
_, err = impl.K8sUtil.UpdateConfigMap(impl.aCDAuthConfig.ACDConfigMapNamespace, cm, client)
285+
if err != nil {
286+
impl.logger.Warnw("config map update failed for install event", "err", err)
287+
} else {
288+
impl.logger.Debugw("config map apply succeeded for install event")
289+
}
290+
}
291+
}
292+
return nil, nil
293+
}
294+
302295
type TelemetryMetaInfo struct {
303296
Url string `json:"url,omitempty"`
304297
UCID string `json:"ucid,omitempty"`

0 commit comments

Comments
 (0)