Skip to content

Commit f5c3f72

Browse files
Merge pull request #1 from AdminTurnedDevOps/feat/learn
Learn function removed
2 parents 80c886f + f347a1a commit f5c3f72

File tree

6 files changed

+156
-90
lines changed

6 files changed

+156
-90
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ Although numbers 1 and 2 are drastically important, number 3 is the make or brea
1515

1616
All applications should perform as expected, and typically, bad performance stems from an networking issue (unless it's a specific app/code issue)
1717

18+
**PLEASE NOTE**: This is for scanning real-time/current usage, not a forecasting tool that learns over time.
19+
1820
## How Does The ML Piece Work?
1921

2022
SMAnalyzer uses a K-means clustering algorithm, which automatically sorts things into groups based on how similar they are to each other.

cmd/learn.go

Lines changed: 0 additions & 59 deletions
This file was deleted.

cmd/monitor.go

Lines changed: 74 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,63 +6,113 @@ import (
66
"log"
77
"time"
88

9+
"smanalyzer/pkg/istio"
10+
"smanalyzer/pkg/k8s"
11+
"smanalyzer/pkg/output"
12+
913
"github.com/spf13/cobra"
1014
)
1115

1216
var monitorCmd = &cobra.Command{
1317
Use: "monitor",
14-
Short: "Continuously monitor service mesh for anomalies",
15-
Long: `Runs continuous monitoring of the service mesh, detecting anomalies in real-time
16-
and reporting them as they occur. Requires a baseline model to be learned first.`,
18+
Short: "Continuously monitor service mesh metrics",
19+
Long: `Runs continuous monitoring of the service mesh, displaying real-time metrics
20+
for all services including request counts, error rates, response times, and more.`,
1721
Run: runMonitor,
1822
}
1923

2024
var (
21-
monitorInterval time.Duration
22-
modelPath string
23-
outputFormat string
25+
monitorInterval time.Duration
26+
monitorNamespace string
27+
outputFormat string
2428
)
2529

2630
func init() {
2731
rootCmd.AddCommand(monitorCmd)
28-
32+
2933
monitorCmd.Flags().DurationVarP(&monitorInterval, "interval", "i", 30*time.Second, "Monitoring interval (e.g., 30s, 1m)")
30-
monitorCmd.Flags().StringVarP(&modelPath, "model", "m", "", "Path to learned baseline model")
31-
monitorCmd.Flags().StringVarP(&outputFormat, "format", "f", "text", "Output format (text, table, json)")
34+
monitorCmd.Flags().StringVarP(&monitorNamespace, "namespace", "n", "default", "Kubernetes namespace to monitor")
35+
monitorCmd.Flags().StringVarP(&outputFormat, "format", "f", "table", "Output format (text, table, json)")
3236
}
3337

3438
func runMonitor(cmd *cobra.Command, args []string) {
3539
ctx := context.Background()
36-
37-
fmt.Printf("Starting continuous service mesh monitoring...\n")
40+
41+
fmt.Printf("Starting service mesh monitoring...\n")
42+
fmt.Printf("Namespace: %s\n", monitorNamespace)
3843
fmt.Printf("Interval: %v\n", monitorInterval)
3944
fmt.Printf("Output format: %s\n", outputFormat)
40-
41-
if modelPath != "" {
42-
fmt.Printf("Using model: %s\n", modelPath)
43-
}
44-
45+
fmt.Println()
46+
4547
if err := performMonitoring(ctx); err != nil {
4648
log.Fatalf("Monitoring failed: %v", err)
4749
}
4850
}
4951

5052
func performMonitoring(ctx context.Context) error {
51-
fmt.Println("Loading baseline model...")
52-
fmt.Println("Starting monitoring loop...")
53-
53+
// Connect to Kubernetes cluster
54+
k8sClient, err := k8s.NewClient()
55+
if err != nil {
56+
return fmt.Errorf("failed to create Kubernetes client: %w", err)
57+
}
58+
59+
if err := k8sClient.CheckConnection(ctx); err != nil {
60+
return fmt.Errorf("failed to connect to cluster: %w", err)
61+
}
62+
63+
// Initialize service discovery
64+
serviceDiscovery := istio.NewServiceDiscovery(k8sClient.Clientset)
65+
66+
// Initialize output formatter
67+
formatter := output.NewFormatter(outputFormat)
68+
69+
fmt.Println("Connected to cluster, starting monitoring loop...")
70+
fmt.Println()
71+
5472
ticker := time.NewTicker(monitorInterval)
5573
defer ticker.Stop()
56-
74+
5775
for {
5876
select {
5977
case <-ctx.Done():
6078
fmt.Println("Monitoring stopped")
6179
return nil
6280
case <-ticker.C:
63-
fmt.Printf("[%s] Checking for anomalies...\n", time.Now().Format("15:04:05"))
64-
65-
time.Sleep(1 * time.Second)
81+
if err := collectAndDisplayMetrics(ctx, serviceDiscovery, formatter); err != nil {
82+
fmt.Printf("Error collecting metrics: %v\n", err)
83+
}
6684
}
6785
}
68-
}
86+
}
87+
88+
func collectAndDisplayMetrics(ctx context.Context, sd *istio.ServiceDiscovery, formatter *output.Formatter) error {
89+
// Discover services
90+
services, err := sd.DiscoverServices(ctx, monitorNamespace)
91+
if err != nil {
92+
return fmt.Errorf("failed to discover services: %w", err)
93+
}
94+
95+
fmt.Println("Please Note: This is a continuous monitoring loop. Press CTRL + C to leave")
96+
fmt.Println()
97+
98+
for _, s := range services {
99+
if len(s) == 0 {
100+
fmt.Printf("[%s] No services found in namespace %s\n", time.Now().Format("15:04:05"), monitorNamespace)
101+
break
102+
}
103+
}
104+
105+
// Collect metrics for each service
106+
var allMetrics []*istio.ServiceMeshMetrics
107+
for _, serviceName := range services {
108+
metrics, err := sd.CollectMetrics(ctx, monitorNamespace, serviceName)
109+
if err != nil {
110+
fmt.Printf("Warning: failed to collect metrics for %s: %v\n", serviceName, err)
111+
continue
112+
}
113+
allMetrics = append(allMetrics, metrics)
114+
}
115+
116+
// Display metrics
117+
return formatter.DisplayMetrics(allMetrics)
118+
}

cmd/root.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@ var (
1515

1616
var rootCmd = &cobra.Command{
1717
Use: "smanalyzer",
18-
Short: "Service Mesh AI Anomaly Detection System",
19-
Long: `SMAnalyzer is an ML-powered system that learns normal behavior patterns
20-
in your Kubernetes Service Mesh and tells you the anomalies in network traffic,
21-
circuit breaking, retries, and timeouts using time series analysis and clustering algorithms.`,
18+
Short: "Service Mesh Monitoring and Analysis System",
19+
Long: `SMAnalyzer monitors your Kubernetes Service Mesh in real-time, displaying
20+
metrics for network traffic, circuit breaking, retries, and timeouts. It can also
21+
scan for anomalies using ML-powered clustering algorithms.`,
2222
}
2323

2424
func Execute() error {

cmd/scan.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ func performScan(ctx context.Context) error {
8686

8787
clusteringEngine := ml.NewClusteringEngine(mlConfig)
8888
detector := anomaly.NewDetector(detectionConfig, clusteringEngine)
89-
formatter := output.NewFormatter(output.Format(config.Output.Format))
89+
formatter := output.NewFormatter(config.Output.Format)
9090

9191
fmt.Println("Collecting service mesh metrics...")
9292

pkg/output/formatter.go

Lines changed: 75 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
package output
22

33
import (
4+
"encoding/json"
45
"fmt"
56
"strings"
67
"time"
78
"smanalyzer/pkg/anomaly"
9+
"smanalyzer/pkg/istio"
810
)
911

1012
type Format string
@@ -19,8 +21,8 @@ type Formatter struct {
1921
format Format
2022
}
2123

22-
func NewFormatter(format Format) *Formatter {
23-
return &Formatter{format: format}
24+
func NewFormatter(format string) *Formatter {
25+
return &Formatter{format: Format(format)}
2426
}
2527

2628
func (f *Formatter) FormatAnomalies(anomalies []anomaly.Anomaly) string {
@@ -105,4 +107,75 @@ func (f *Formatter) truncate(s string, maxLen int) string {
105107
return s
106108
}
107109
return s[:maxLen-3] + "..."
110+
}
111+
112+
func (f *Formatter) DisplayMetrics(metrics []*istio.ServiceMeshMetrics) error {
113+
switch f.format {
114+
case JSON:
115+
return f.displayMetricsJSON(metrics)
116+
case Table:
117+
return f.displayMetricsTable(metrics)
118+
default:
119+
return f.displayMetricsText(metrics)
120+
}
121+
}
122+
123+
func (f *Formatter) displayMetricsText(metrics []*istio.ServiceMeshMetrics) error {
124+
if len(metrics) == 0 {
125+
fmt.Printf("[%s] No services found\n", time.Now().Format("15:04:05"))
126+
return nil
127+
}
128+
129+
fmt.Printf("[%s] Service Mesh Metrics:\n\n", time.Now().Format("15:04:05"))
130+
131+
for _, m := range metrics {
132+
fmt.Printf("Service: %s.%s\n", m.ServiceName, m.Namespace)
133+
fmt.Printf(" Request Count: %d\n", m.RequestCount)
134+
fmt.Printf(" Error Rate: %.2f%%\n", m.ErrorRate*100)
135+
fmt.Printf(" Response Time: %v\n", m.ResponseTime)
136+
fmt.Printf(" Circuit Breakers: %d\n", m.CircuitBreakers)
137+
fmt.Printf(" Retry Count: %d\n", m.RetryCount)
138+
fmt.Printf(" Timeout Count: %d\n", m.TimeoutCount)
139+
fmt.Println()
140+
}
141+
142+
return nil
143+
}
144+
145+
func (f *Formatter) displayMetricsTable(metrics []*istio.ServiceMeshMetrics) error {
146+
if len(metrics) == 0 {
147+
fmt.Printf("[%s] No services found\n", time.Now().Format("15:04:05"))
148+
return nil
149+
}
150+
151+
fmt.Printf("[%s] Service Mesh Metrics:\n\n", time.Now().Format("15:04:05"))
152+
fmt.Printf("%-20s %-10s %-12s %-8s %-12s %-8s %-8s %-8s\n",
153+
"SERVICE", "NAMESPACE", "REQ_COUNT", "ERR_RATE", "RESP_TIME", "CIRCUIT", "RETRIES", "TIMEOUTS")
154+
fmt.Printf("%-20s %-10s %-12s %-8s %-12s %-8s %-8s %-8s\n",
155+
"-------", "---------", "---------", "--------", "---------", "-------", "-------", "--------")
156+
157+
for _, m := range metrics {
158+
service := f.truncate(m.ServiceName, 19)
159+
namespace := f.truncate(m.Namespace, 9)
160+
161+
fmt.Printf("%-20s %-10s %-12d %-8.2f %-12v %-8d %-8d %-8d\n",
162+
service, namespace, m.RequestCount, m.ErrorRate*100,
163+
m.ResponseTime, m.CircuitBreakers, m.RetryCount, m.TimeoutCount)
164+
}
165+
fmt.Println()
166+
167+
return nil
168+
}
169+
170+
func (f *Formatter) displayMetricsJSON(metrics []*istio.ServiceMeshMetrics) error {
171+
data, err := json.MarshalIndent(metrics, "", " ")
172+
if err != nil {
173+
return fmt.Errorf("failed to marshal metrics: %w", err)
174+
}
175+
176+
fmt.Printf("[%s] Service Mesh Metrics (JSON):\n", time.Now().Format("15:04:05"))
177+
fmt.Println(string(data))
178+
fmt.Println()
179+
180+
return nil
108181
}

0 commit comments

Comments
 (0)