Skip to content

Commit

Permalink
Send Apache stats based on mod_status. Closes #15.
Browse files Browse the repository at this point in the history
  • Loading branch information
darron committed Jan 11, 2016
1 parent cd2ebd9 commit b3bc754
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 0 deletions.
40 changes: 40 additions & 0 deletions cmd/apache.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ func startApache(cmd *cobra.Command, args []string) {
if matches != nil {
fmt.Printf("Found %d matches.\n", len(matches)-1)
SendMetrics(matches)
processMap := createProcessMemMap(matches)
// Let's get the Apache details and then submit those.
apaches := GetApacheServerStats()
SendApacheServerStats(apaches, processMap)
} else {
fmt.Printf("Did not find any matches.\n")
}
Expand All @@ -60,6 +64,31 @@ func init() {
RootCmd.AddCommand(apacheCmd)
}

// SendApacheServerStats sends tagged Apache stats to Datadog
func SendApacheServerStats(apache []ApacheProcess, procs map[int]uint64) {
var err error
dog := DogConnect()
for _, server := range apache {
pid := int(server.Pid)
memory := procs[pid]
if memory > 0 {
dog.Tags = append(dog.Tags, fmt.Sprintf("site:%s", server.Vhost))
err = dog.Histogram("apache2.rss_memory_tagged", float64(memory), dog.Tags, 1)
if err != nil {
Log("Error sending tagged rss_memory stats for Apache", "info")
}
}
}
}

// GetApacheServerStats grabs info from mod_status and parses it.
func GetApacheServerStats() []ApacheProcess {
htmlContent := getServerStatus("")
stringResults := parseServerStatus(htmlContent)
apaches := parseProcessStats(stringResults)
return apaches
}

// getServerStatus returns the HTML nodes from the Apache serverStatus page.
func getServerStatus(server string) *html.Node {
serverStatus := ""
Expand Down Expand Up @@ -118,3 +147,14 @@ func parseProcessStats(processes []string) []ApacheProcess {
}
return stats
}

// Take a slice of ProcessList items and create a map.
func createProcessMemMap(p []ProcessList) map[int]uint64 {
m := make(map[int]uint64)
for _, proc := range p {
pid := proc.Pid
mem := proc.Pmem
m[pid] = mem
}
return m
}
74 changes: 74 additions & 0 deletions cmd/apache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,77 @@ func TestParseServerStats(t *testing.T) {
t.Error("That's bad - we should see 9 Apache structs.")
}
}

func createTestProcessList() []ProcessList {
var procs []ProcessList
var proc ProcessList
proc = ProcessList{Pname: "apache2", Pid: 10434, Pmem: 10520, Puser: 90, Psys: 64}
procs = append(procs, proc)
proc = ProcessList{Pname: "apache2", Pid: 10360, Pmem: 20520, Puser: 90, Psys: 64}
procs = append(procs, proc)
proc = ProcessList{Pname: "apache2", Pid: 10282, Pmem: 30520, Puser: 90, Psys: 64}
procs = append(procs, proc)
proc = ProcessList{Pname: "apache2", Pid: 10345, Pmem: 15520, Puser: 90, Psys: 64}
procs = append(procs, proc)
proc = ProcessList{Pname: "apache2", Pid: 10475, Pmem: 25520, Puser: 90, Psys: 64}
procs = append(procs, proc)
return procs
}

func TestCreateProcessMemMap(t *testing.T) {
procs := createTestProcessList()
processMap := createProcessMemMap(procs)
if processMap[10434] != uint64(10520) {
t.Error("That's incorrect - it should be uint64(10520).")
}
}

func createTestApacheList() []ApacheProcess {
var stats []ApacheProcess
var apache ApacheProcess
apache = ApacheProcess{Pid: 10434, Vhost: "andy.bam.nonwebdev.com"}
stats = append(stats, apache)
apache = ApacheProcess{Pid: 10360, Vhost: "jon.bam.nonwebdev.com"}
stats = append(stats, apache)
apache = ApacheProcess{Pid: 10282, Vhost: "darron.bam.nonwebdev.com"}
stats = append(stats, apache)
apache = ApacheProcess{Pid: 10345, Vhost: "darron.bam.nonwebdev.com"}
stats = append(stats, apache)
apache = ApacheProcess{Pid: 10475, Vhost: "robb.bam.nonwebdev.com"}
stats = append(stats, apache)
return stats
}

// Testing to see if the stats get sent.
func TestSendApacheServerStats(t *testing.T) {
procs := createTestProcessList()
if len(procs) != 5 {
t.Error("That's a problem - there should be 5 processes.")
}
apaches := createTestApacheList()
if len(apaches) != 5 {
t.Error("That's a problem - there should be 5 Apaches.")
}
procMap := createProcessMemMap(procs)
SendApacheServerStats(apaches, procMap)
}

// Adding an extra Apache process without corresponding memory info.
func TestSendApacheServerStatsWithExtraApache(t *testing.T) {
procs := createTestProcessList()
apaches := createTestApacheList()
apache := ApacheProcess{Pid: 10800, Vhost: "wildcard.bam.nonwebdev.com"}
apaches = append(apaches, apache)
procMap := createProcessMemMap(procs)
SendApacheServerStats(apaches, procMap)
}

// Adding an extra Process without a matching Apache process.
func TestSendApacheServerStatsWithExtraProcess(t *testing.T) {
procs := createTestProcessList()
proc := ProcessList{Pname: "apache2", Pid: 16475, Pmem: 255520, Puser: 90, Psys: 64}
procs = append(procs, proc)
apaches := createTestApacheList()
procMap := createProcessMemMap(procs)
SendApacheServerStats(apaches, procMap)
}

0 comments on commit b3bc754

Please sign in to comment.