Skip to content

Commit

Permalink
Add event reporting (#60)
Browse files Browse the repository at this point in the history
The following flags can disable reporting:

* Helm chart: `--set telemetry.enabled=false`
* CLI: `odigos install --telemetry=false`
  • Loading branch information
edeNFed authored Jan 28, 2023
1 parent 1b2e8e7 commit 157128f
Show file tree
Hide file tree
Showing 4 changed files with 221 additions and 12 deletions.
10 changes: 6 additions & 4 deletions cli/cmd/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@ const (
)

var (
namespaceFlag string
versionFlag string
skipWait bool
namespaceFlag string
versionFlag string
skipWait bool
telemetryEnabled bool
)

type ResourceCreationFunc func(ctx context.Context, cmd *cobra.Command, client *kube.Client, ns string) error
Expand Down Expand Up @@ -151,7 +152,7 @@ func createInstrumentor(ctx context.Context, cmd *cobra.Command, client *kube.Cl
return err
}

_, err = client.AppsV1().Deployments(ns).Create(ctx, resources.NewInstrumentorDeployment(versionFlag), metav1.CreateOptions{})
_, err = client.AppsV1().Deployments(ns).Create(ctx, resources.NewInstrumentorDeployment(versionFlag, telemetryEnabled), metav1.CreateOptions{})
return err
}

Expand Down Expand Up @@ -285,4 +286,5 @@ func init() {
installCmd.Flags().StringVarP(&namespaceFlag, "namespace", "n", defaultNamespace, "target namespace for Odigos installation")
installCmd.Flags().StringVar(&versionFlag, "version", OdigosVersion, "target version for Odigos installation")
installCmd.Flags().BoolVar(&skipWait, "nowait", false, "Skip waiting for pods to be ready")
installCmd.Flags().BoolVar(&telemetryEnabled, "telemetry", true, "Enable telemetry")
}
73 changes: 65 additions & 8 deletions cli/cmd/resources/instrumentor.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,17 @@ func NewInstrumentorClusterRole() *rbacv1.ClusterRole {
"pods",
},
},
{
Verbs: []string{
"list",
"watch",
"get",
},
APIGroups: []string{""},
Resources: []string{
"nodes",
},
},
{
Verbs: []string{
"get",
Expand Down Expand Up @@ -271,6 +282,47 @@ func NewInstrumentorClusterRole() *rbacv1.ClusterRole {
"odigosconfigurations",
},
},
{
Verbs: []string{
"create",
"delete",
"get",
"list",
"patch",
"update",
"watch",
},
APIGroups: []string{
"odigos.io",
},
Resources: []string{
"destinations",
},
},
{
Verbs: []string{
"update",
},
APIGroups: []string{
"odigos.io",
},
Resources: []string{
"destinations/finalizers",
},
},
{
Verbs: []string{
"get",
"patch",
"update",
},
APIGroups: []string{
"odigos.io",
},
Resources: []string{
"destinations/status",
},
},
},
}
}
Expand Down Expand Up @@ -300,7 +352,18 @@ func NewInstrumentorClusterRoleBinding(ns string) *rbacv1.ClusterRoleBinding {
}
}

func NewInstrumentorDeployment(version string) *appsv1.Deployment {
func NewInstrumentorDeployment(version string, telemetryEnabled bool) *appsv1.Deployment {
args := []string{
"--health-probe-bind-address=:8081",
"--metrics-bind-address=127.0.0.1:8080",
"--leader-elect",
fmt.Sprintf("--lang-detector-tag=%s", version),
fmt.Sprintf("--lang-detector-image=%s", langDetectorImage),
}

if !telemetryEnabled {
args = append(args, "--telemetry-disabled")
}
return &appsv1.Deployment{
TypeMeta: metav1.TypeMeta{
Kind: "Deployment",
Expand Down Expand Up @@ -359,13 +422,7 @@ func NewInstrumentorDeployment(version string) *appsv1.Deployment {
Command: []string{
"/app",
},
Args: []string{
"--health-probe-bind-address=:8081",
"--metrics-bind-address=127.0.0.1:8080",
"--leader-elect",
fmt.Sprintf("--lang-detector-tag=%s", version),
fmt.Sprintf("--lang-detector-image=%s", langDetectorImage),
},
Args: args,
Env: []corev1.EnvVar{
{
Name: "CURRENT_NS",
Expand Down
7 changes: 7 additions & 0 deletions instrumentor/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package main

import (
"flag"
"github.com/keyval-dev/odigos/instrumentor/report"
"os"

v1 "github.com/keyval-dev/odigos/api/odigos/v1alpha1"
Expand Down Expand Up @@ -56,6 +57,7 @@ func main() {
var langDetectorTag string
var langDetectorImage string
var deleteLangDetectionPods bool
var telemetryDisabled bool

flag.StringVar(&metricsAddr, "metrics-bind-address", ":8080", "The address the metric endpoint binds to.")
flag.StringVar(&probeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.")
Expand All @@ -65,6 +67,7 @@ func main() {
flag.StringVar(&langDetectorTag, "lang-detector-tag", "latest", "container tag to use for lang detection")
flag.StringVar(&langDetectorImage, "lang-detector-image", "ghcr.io/keyval-dev/odigos/lang-detector", "container image to use for lang detection")
flag.BoolVar(&deleteLangDetectionPods, "delete-detection-pods", true, "Automatic termination of detection pods")
flag.BoolVar(&telemetryDisabled, "telemetry-disabled", false, "Disable telemetry")

opts := zap.Options{
Development: true,
Expand Down Expand Up @@ -129,6 +132,10 @@ func main() {
os.Exit(1)
}

if !telemetryDisabled {
go report.Start(mgr.GetClient())
}

setupLog.Info("starting manager")
if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil {
setupLog.Error(err, "problem running manager")
Expand Down
143 changes: 143 additions & 0 deletions instrumentor/report/events.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
package report

import (
"bytes"
"context"
"encoding/json"
"github.com/google/uuid"
odigosv1 "github.com/keyval-dev/odigos/api/odigos/v1alpha1"
"github.com/keyval-dev/odigos/common"
corev1 "k8s.io/api/core/v1"
"net/http"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"time"
)

const (
endpoint = "https://349trlge22.execute-api.us-east-1.amazonaws.com/default/odigos_events_lambda"
)

func Start(c client.Client) {
installationId := uuid.New().String()
time.Sleep(1 * time.Minute)
reportEvent(c, installationId)

time.Sleep(5 * time.Minute)
reportEvent(c, installationId)

for range time.Tick(24 * time.Hour) {
reportEvent(c, installationId)
}
}

func reportEvent(c client.Client, installationId string) {
err := report(c, installationId)
if err != nil {
ctrl.Log.Error(err, "error reporting event")
}
}

type event struct {
SendingTraces bool `json:"sending_traces"`
SendingMetrics bool `json:"sending_metrics"`
SendingLogs bool `json:"sending_logs"`
Backends []string `json:"backends"`
GoApps int `json:"go_apps"`
JavaApps int `json:"java_apps"`
PythonApps int `json:"python_apps"`
DotnetApps int `json:"dotnet_apps"`
JsApps int `json:"js_apps"`
UnrecognizedApps int `json:"unrecognized_apps"`
NumOfNodes int `json:"num_of_nodes"`
InstallationID string `json:"installation_id"`
}

func report(c client.Client, installationId string) error {
ctx := context.Background()
var dests odigosv1.DestinationList
err := c.List(ctx, &dests)
if err != nil {
return err
}

traces := false
metrics := false
logs := false
var backends []string
for _, dest := range dests.Items {
backends = append(backends, string(dest.Spec.Type))
for _, s := range dest.Spec.Signals {
if s == common.TracesObservabilitySignal {
traces = true
} else if s == common.MetricsObservabilitySignal {
metrics = true
} else if s == common.LogsObservabilitySignal {
logs = true
}
}
}

var nodes corev1.NodeList
err = c.List(ctx, &nodes)
if err != nil {
return err
}

var apps odigosv1.InstrumentedApplicationList
err = c.List(ctx, &apps)
if err != nil {
return err
}

goApps := 0
javaApps := 0
pythonApps := 0
dotnetApps := 0
jsApps := 0
unrecognizedApps := 0
for _, app := range apps.Items {
for _, l := range app.Spec.Languages {
switch l.Language {
case common.GoProgrammingLanguage:
goApps++
case common.JavaProgrammingLanguage:
javaApps++
case common.PythonProgrammingLanguage:
pythonApps++
case common.DotNetProgrammingLanguage:
dotnetApps++
case common.JavascriptProgrammingLanguage:
jsApps++
default:
unrecognizedApps++
}
}

if len(app.Spec.Languages) == 0 {
unrecognizedApps++
}
}

reportedEvent := &event{
Backends: backends,
SendingTraces: traces,
SendingMetrics: metrics,
SendingLogs: logs,
NumOfNodes: len(nodes.Items),
GoApps: goApps,
JavaApps: javaApps,
PythonApps: pythonApps,
DotnetApps: dotnetApps,
JsApps: jsApps,
UnrecognizedApps: unrecognizedApps,
InstallationID: installationId,
}
jsonReport, err := json.Marshal(reportedEvent)
if err != nil {
return err
}

_, err = http.Post(endpoint, "application/json", bytes.NewBuffer(jsonReport))
return err
}

0 comments on commit 157128f

Please sign in to comment.