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
2727type 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
4238type TelemetryEventClient interface {
4339 GetTelemetryMetaInfo () (* TelemetryMetaInfo , error )
40+ SendTelemtryInstallEventEA () (* TelemetryEventType , error )
4441}
4542
4643func 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
10591const 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
234202func (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+
302295type TelemetryMetaInfo struct {
303296 Url string `json:"url,omitempty"`
304297 UCID string `json:"ucid,omitempty"`
0 commit comments