-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 8134ebb
Showing
3 changed files
with
212 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
# Binaries | ||
beeping-cli | ||
|
||
# Compiled Object files, Static and Dynamic libs (Shared Objects) | ||
*.o | ||
*.a | ||
*.so | ||
|
||
# Folders | ||
_obj | ||
_test | ||
vendor | ||
|
||
# IDE | ||
.idea | ||
|
||
# Architecture specific extensions/prefixes | ||
*.[568vq] | ||
[568vq].out | ||
|
||
*.cgo1.go | ||
*.cgo2.c | ||
_cgo_defun.c | ||
_cgo_gotypes.go | ||
_cgo_export.* | ||
|
||
_testmain.go | ||
|
||
*.exe | ||
*.test | ||
*.prof |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# beeping-cli | ||
|
||
A GO client for [beeping](https://github.com/yanc0/beeping). | ||
For now, it's only send BeePing response to [greedee](https://github.com/yanc0/greedee) in collectd Metric format. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,176 @@ | ||
package main | ||
|
||
import ( | ||
"bytes" | ||
"encoding/json" | ||
"flag" | ||
"fmt" | ||
"github.com/yanc0/beeping/sslcheck" | ||
"github.com/yanc0/greedee/collectd" | ||
"log" | ||
"net/http" | ||
"os" | ||
"time" | ||
) | ||
|
||
// TODO: use a BeePing package | ||
type Check struct { | ||
URL string `json:"url" binding:"required"` | ||
Pattern string `json:"pattern"` | ||
Header string `json:"header"` | ||
Insecure bool `json:"insecure"` | ||
Timeout time.Duration `json:"timeout"` | ||
Auth string `json:"auth"` | ||
} | ||
|
||
type Timeline struct { | ||
NameLookup int64 `json:"name_lookup"` | ||
Connect int64 `json:"connect"` | ||
Pretransfer int64 `json:"pretransfer"` | ||
StartTransfer int64 `json:"starttransfer"` | ||
} | ||
|
||
type Geo struct { | ||
Country string `json:"country"` | ||
City string `json:"city,omitempty"` | ||
IP string `json:"ip"` | ||
} | ||
|
||
type Response struct { | ||
HTTPStatus string `json:"http_status"` | ||
HTTPStatusCode int `json:"http_status_code"` | ||
HTTPBodyPattern bool `json:"http_body_pattern"` | ||
HTTPHeader bool `json:"http_header"` | ||
HTTPRequestTime int64 `json:"http_request_time"` | ||
|
||
InstanceName string `json:"instance_name"` | ||
|
||
DNSLookup int64 `json:"dns_lookup"` | ||
TCPConnection int64 `json:"tcp_connection"` | ||
TLSHandshake int64 `json:"tls_handshake,omitempty"` | ||
ServerProcessing int64 `json:"server_processing"` | ||
ContentTransfer int64 `json:"content_transfer"` | ||
|
||
Timeline *Timeline `json:"timeline"` | ||
Geo *Geo `json:"geo,omitempty"` | ||
SSL *sslcheck.CheckSSL `json:"ssl,omitempty"` | ||
} | ||
|
||
var beepingURL *string | ||
var checkURL *string | ||
var timeout *int64 | ||
var pattern *string | ||
var host *string | ||
var greedeeURL *string | ||
var greedeeUser *string | ||
var greedeePass *string | ||
|
||
func main() { | ||
|
||
beepingURL = flag.String("beeping", "http://localhost:8080", "URL of your BeePing instance") | ||
checkURL = flag.String("check", "", "URL we want to check") | ||
timeout = flag.Int64("timeout", 20, "BeePing check timeout") | ||
pattern = flag.String("pattern", "", "pattern that's need to be found in the body") | ||
host = flag.String("host", "test.test.prod.host.beeping", "Collectd metric's host entry, for example:'customer.app.env.servername'") | ||
greedeeURL = flag.String("greedee", "http://localhost:9223", "URL of your Greedee instance") | ||
greedeeUser = flag.String("greedeeUser", "", "Greedee user if configured with basic auth") | ||
greedeePass = flag.String("greedeePass", "", "Greedee password if configured with basic auth") | ||
flag.Parse() | ||
|
||
if *checkURL == "" { | ||
fmt.Printf("Usage:\n\n") | ||
flag.PrintDefaults() | ||
os.Exit(1) | ||
} | ||
|
||
bpResp, err := requestBeepingCheck() | ||
|
||
if err != nil { | ||
log.Fatal(fmt.Printf("[FATAL] Beeping check failed: %s\n\n", err)) | ||
} | ||
|
||
sendCollectdMetricsToGreedee(bpResp) | ||
} | ||
|
||
func requestBeepingCheck() (*Response, error) { | ||
check := &Check{ | ||
*checkURL, | ||
*pattern, | ||
"", | ||
false, | ||
time.Duration(*timeout) * time.Second, | ||
"", | ||
} | ||
|
||
jsonReq, _ := json.Marshal(check) | ||
resp, err := http.Post(*beepingURL+"/check", "application/json", bytes.NewBuffer(jsonReq)) | ||
|
||
if err != nil { | ||
return nil, err | ||
} else { | ||
defer resp.Body.Close() | ||
response := &Response{} | ||
decoder := json.NewDecoder(resp.Body) | ||
err := decoder.Decode(&response) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return response, nil | ||
} | ||
} | ||
|
||
func createCMetric(timeNow int64, cMType string, cMValues float64) *collectd.CollectDMetric { | ||
cMetric := collectd.CollectDMetric{ | ||
Host: *host, | ||
Plugin: "beeping", | ||
PluginInstance: "", | ||
Type: cMType, | ||
TypeInstance: "", | ||
Time: float64(timeNow), | ||
Interval: 30, // why ? | ||
DSTypes: []string{"gauge"}, | ||
DSNames: []string{"value"}, | ||
Values: []float64{cMValues}, | ||
} | ||
return &cMetric | ||
} | ||
|
||
func convertBoolToCMetricVal(value bool) float64 { | ||
if value { | ||
return float64(1) | ||
} else { | ||
return float64(0) | ||
} | ||
} | ||
// Transform Beeping Response to a map of collectd.Metrics and send it to Greedee | ||
func sendCollectdMetricsToGreedee(bpResp *Response) { | ||
|
||
|
||
cMetrics := []*collectd.CollectDMetric{} | ||
timeNow := time.Now().Unix() | ||
|
||
cMetrics = append(cMetrics, createCMetric(timeNow, "http_status_code", float64(bpResp.HTTPStatusCode))) | ||
cMetrics = append(cMetrics, createCMetric(timeNow, "http_body_pattern", convertBoolToCMetricVal(bpResp.HTTPBodyPattern))) | ||
cMetrics = append(cMetrics, createCMetric(timeNow, "http_request_time", float64(bpResp.HTTPRequestTime))) | ||
cMetrics = append(cMetrics, createCMetric(timeNow, "dns_lookup", float64(bpResp.DNSLookup))) | ||
cMetrics = append(cMetrics, createCMetric(timeNow, "tcp_connection", float64(bpResp.TCPConnection))) | ||
cMetrics = append(cMetrics, createCMetric(timeNow, "tls_handshake", float64(bpResp.TLSHandshake))) | ||
cMetrics = append(cMetrics, createCMetric(timeNow, "content_transfer", float64(bpResp.ContentTransfer))) | ||
cMetrics = append(cMetrics, createCMetric(timeNow, "server_processing", float64(bpResp.ServerProcessing))) | ||
cMetrics = append(cMetrics, createCMetric(timeNow, "cert_expiry_days_left", float64(bpResp.SSL.CertExpiryDaysLeft))) | ||
|
||
cMetricsJson, _ := json.Marshal(cMetrics) | ||
httpClient := &http.Client{} | ||
gdReq, _ := http.NewRequest("POST", *greedeeURL+"/metrics", bytes.NewBuffer(cMetricsJson)) | ||
gdReq.Header.Set("Content-Type", "application/json") | ||
|
||
if greedeeUser != nil && greedeePass != nil { | ||
gdReq.SetBasicAuth(*greedeeUser, *greedeePass) | ||
} | ||
|
||
_, err := httpClient.Do(gdReq) | ||
|
||
if err != nil { | ||
log.Fatal(fmt.Printf("[FATAL] Greedee Error: %s\n\n", err)) | ||
} | ||
} |