@@ -31,6 +31,7 @@ import (
31
31
"github.com/devtron-labs/devtron/pkg/auth/user/bean"
32
32
bean3 "github.com/devtron-labs/devtron/pkg/cluster/bean"
33
33
module2 "github.com/devtron-labs/devtron/pkg/module/bean"
34
+
34
35
ucidService "github.com/devtron-labs/devtron/pkg/ucid"
35
36
cron3 "github.com/devtron-labs/devtron/util/cron"
36
37
"go.opentelemetry.io/otel"
@@ -39,6 +40,9 @@ import (
39
40
40
41
"github.com/devtron-labs/common-lib/utils/k8s"
41
42
"github.com/devtron-labs/devtron/internal/sql/repository"
43
+ appRepository "github.com/devtron-labs/devtron/internal/sql/repository/app"
44
+ "github.com/devtron-labs/devtron/internal/sql/repository/helper"
45
+ "github.com/devtron-labs/devtron/internal/sql/repository/pipelineConfig"
42
46
"github.com/devtron-labs/devtron/pkg/auth/sso"
43
47
user2 "github.com/devtron-labs/devtron/pkg/auth/user"
44
48
"github.com/devtron-labs/devtron/pkg/cluster"
@@ -75,6 +79,10 @@ type TelemetryEventClientImpl struct {
75
79
cloudProviderIdentifierService cloudProviderIdentifier.ProviderIdentifierService
76
80
telemetryConfig TelemetryConfig
77
81
globalEnvVariables * util.GlobalEnvVariables
82
+ // Additional repositories for telemetry metrics (passed from TelemetryEventClientExtended)
83
+ appRepository appRepository.AppRepository
84
+ ciWorkflowRepository pipelineConfig.CiWorkflowRepository
85
+ cdWorkflowRepository pipelineConfig.CdWorkflowRepository
78
86
}
79
87
80
88
type TelemetryEventClient interface {
@@ -120,6 +128,7 @@ func NewTelemetryEventClientImpl(logger *zap.SugaredLogger, client *http.Client,
120
128
telemetryConfig : TelemetryConfig {},
121
129
globalEnvVariables : envVariables .GlobalEnvVariables ,
122
130
userAttributesRepository : userAttributesRepository ,
131
+ // Note: appRepository, ciWorkflowRepository, cdWorkflowRepository will be set by TelemetryEventClientExtended
123
132
}
124
133
125
134
watcher .HeartbeatEventForTelemetry ()
@@ -263,6 +272,166 @@ func (impl *TelemetryEventClientImpl) SummaryDetailsForTelemetry() (cluster []be
263
272
return clusters , users , k8sServerVersion , hostURL , ssoSetup , HelmAppAccessCount , ChartStoreVisitCount , SkippedOnboarding , HelmAppUpdateCounter , helmChartSuccessfulDeploymentCount , ExternalHelmAppClusterCount
264
273
}
265
274
275
+ // New methods for collecting additional telemetry metrics
276
+
277
+ func (impl * TelemetryEventClientImpl ) getHelmAppCount () int {
278
+ count , err := impl .installedAppReadService .GetDeploymentSuccessfulStatusCountForTelemetry ()
279
+ if err != nil {
280
+ impl .logger .Errorw ("error getting helm app count" , "err" , err )
281
+ return - 1
282
+ }
283
+ return count
284
+ }
285
+
286
+ func (impl * TelemetryEventClientImpl ) getDevtronAppCount () int {
287
+ // Use a simple approach - count all active apps that are not jobs
288
+ if impl .appRepository == nil {
289
+ impl .logger .Warnw ("appRepository not available for devtron app count" )
290
+ return - 1
291
+ }
292
+
293
+ // Get all active apps and filter out jobs
294
+ apps , err := impl .appRepository .FindAll ()
295
+ if err != nil {
296
+ impl .logger .Errorw ("error getting all apps for devtron app count" , "err" , err )
297
+ return - 1
298
+ }
299
+
300
+ devtronAppCount := 0
301
+ for _ , app := range apps {
302
+ if app .AppType != helper .Job && app .Active {
303
+ devtronAppCount ++
304
+ }
305
+ }
306
+
307
+ return devtronAppCount
308
+ }
309
+
310
+ func (impl * TelemetryEventClientImpl ) getJobCount () int {
311
+ // Use a simple approach - count all active apps that are jobs
312
+ if impl .appRepository == nil {
313
+ impl .logger .Warnw ("appRepository not available for job count" )
314
+ return - 1
315
+ }
316
+
317
+ apps , err := impl .appRepository .FindAll ()
318
+ if err != nil {
319
+ impl .logger .Errorw ("error getting all apps for job count" , "err" , err )
320
+ return - 1
321
+ }
322
+
323
+ jobCount := 0
324
+ for _ , app := range apps {
325
+ if app .AppType == helper .Job && app .Active {
326
+ jobCount ++
327
+ }
328
+ }
329
+
330
+ return jobCount
331
+ }
332
+
333
+ func (impl * TelemetryEventClientImpl ) getUserCreatedPluginCount () int {
334
+ // Placeholder implementation - would need plugin repository
335
+ // For now, return 0 as we don't have the plugin repository dependency
336
+ impl .logger .Debugw ("getUserCreatedPluginCount not fully implemented - returning 0" )
337
+ return 0
338
+ }
339
+
340
+ func (impl * TelemetryEventClientImpl ) getPolicyCount () map [string ]int {
341
+ // Placeholder implementation - would need policy repository
342
+ // For now, return empty map as we don't have the policy repository dependency
343
+ policyCount := make (map [string ]int )
344
+ policyCount ["global" ] = 0
345
+ policyCount ["cluster" ] = 0
346
+ policyCount ["environment" ] = 0
347
+ policyCount ["application" ] = 0
348
+
349
+ impl .logger .Debugw ("getPolicyCount not fully implemented - returning zeros" )
350
+ return policyCount
351
+ }
352
+
353
+ func (impl * TelemetryEventClientImpl ) getClusterCounts () (physicalCount int , isolatedCount int ) {
354
+ clusters , err := impl .clusterService .FindAllActive ()
355
+ if err != nil {
356
+ impl .logger .Errorw ("error getting cluster counts" , "err" , err )
357
+ return - 1 , - 1
358
+ }
359
+
360
+ physicalCount = 0
361
+ isolatedCount = 0
362
+
363
+ for _ , cluster := range clusters {
364
+ if cluster .IsVirtualCluster {
365
+ isolatedCount ++
366
+ } else {
367
+ physicalCount ++
368
+ }
369
+ }
370
+
371
+ return physicalCount , isolatedCount
372
+ }
373
+
374
+ func (impl * TelemetryEventClientImpl ) getJobPipelineCount () int {
375
+ // Simplified implementation - count job apps as proxy for job pipelines
376
+ // In a more complete implementation, you would count actual CI pipelines for job apps
377
+ jobCount := impl .getJobCount ()
378
+ if jobCount <= 0 {
379
+ return 0
380
+ }
381
+
382
+ // For now, assume each job has at least one pipeline
383
+ // This is a simplification - in reality you'd need to query the CI pipeline repository
384
+ impl .logger .Debugw ("getJobPipelineCount using simplified approach" , "jobCount" , jobCount )
385
+ return jobCount
386
+ }
387
+
388
+ func (impl * TelemetryEventClientImpl ) getJobPipelineTriggeredLast24h () int {
389
+ // Simplified implementation - would need more complex query to filter by job apps
390
+ if impl .ciWorkflowRepository == nil {
391
+ impl .logger .Warnw ("ciWorkflowRepository not available for job pipeline triggered count" )
392
+ return - 1
393
+ }
394
+
395
+ // Get total triggered workflows in last 24h (includes all apps, not just jobs)
396
+ // This is an approximation - in reality you'd need to filter by job apps
397
+ count , err := impl .ciWorkflowRepository .FindAllTriggeredWorkflowCountInLast24Hour ()
398
+ if err != nil {
399
+ impl .logger .Errorw ("error getting triggered workflow count" , "err" , err )
400
+ return - 1
401
+ }
402
+
403
+ // Estimate job pipeline triggers as a fraction of total triggers
404
+ // This is a rough approximation
405
+ jobCount := impl .getJobCount ()
406
+ totalAppCount := impl .getDevtronAppCount () + jobCount
407
+ if totalAppCount > 0 {
408
+ estimatedJobTriggers := (count * jobCount ) / totalAppCount
409
+ impl .logger .Debugw ("estimated job pipeline triggers" , "total" , count , "estimated" , estimatedJobTriggers )
410
+ return estimatedJobTriggers
411
+ }
412
+
413
+ return 0
414
+ }
415
+
416
+ func (impl * TelemetryEventClientImpl ) getJobPipelineSucceededLast24h () int {
417
+ // Placeholder implementation - would need complex query to count successful job pipeline runs
418
+ // For now, return 0 as this requires joining multiple tables and filtering by job apps
419
+ impl .logger .Debugw ("getJobPipelineSucceededLast24h not fully implemented - returning 0" )
420
+ return 0
421
+ }
422
+
423
+ func (impl * TelemetryEventClientImpl ) getAppliedPolicyRowCount () map [string ]int {
424
+ // Placeholder implementation - would need policy enforcement/application tables
425
+ appliedCount := make (map [string ]int )
426
+ appliedCount ["global" ] = 0
427
+ appliedCount ["cluster" ] = 0
428
+ appliedCount ["environment" ] = 0
429
+ appliedCount ["application" ] = 0
430
+
431
+ impl .logger .Debugw ("getAppliedPolicyRowCount not fully implemented - returning zeros" )
432
+ return appliedCount
433
+ }
434
+
266
435
func (impl * TelemetryEventClientImpl ) SummaryEventForTelemetryEA () {
267
436
err := impl .SendSummaryEvent (string (Summary ))
268
437
if err != nil {
@@ -310,6 +479,18 @@ func (impl *TelemetryEventClientImpl) SendSummaryEvent(eventType string) error {
310
479
payload .HelmChartSuccessfulDeploymentCount = helmChartSuccessfulDeploymentCount
311
480
payload .ExternalHelmAppClusterCount = ExternalHelmAppClusterCount
312
481
482
+ // Collect new telemetry metrics
483
+ payload .HelmAppCount = impl .getHelmAppCount ()
484
+ payload .DevtronAppCount = impl .getDevtronAppCount ()
485
+ payload .JobCount = impl .getJobCount ()
486
+ payload .JobPipelineCount = impl .getJobPipelineCount ()
487
+ payload .JobPipelineTriggeredLast24h = impl .getJobPipelineTriggeredLast24h ()
488
+ payload .JobPipelineSucceededLast24h = impl .getJobPipelineSucceededLast24h ()
489
+ payload .UserCreatedPluginCount = impl .getUserCreatedPluginCount ()
490
+ payload .PolicyCount = impl .getPolicyCount ()
491
+ payload .AppliedPolicyRowCount = impl .getAppliedPolicyRowCount ()
492
+ payload .PhysicalClusterCount , payload .IsolatedClusterCount = impl .getClusterCounts ()
493
+
313
494
payload .ClusterProvider , err = impl .GetCloudProvider ()
314
495
if err != nil {
315
496
impl .logger .Errorw ("error while getting cluster provider" , "error" , err )
0 commit comments