Skip to content

Commit

Permalink
Merge pull request #14 from Intellection/fix-index-out-of-range
Browse files Browse the repository at this point in the history
Fix index out of range panic
  • Loading branch information
zacblazic authored Mar 18, 2020
2 parents 51939b5 + 67ec97b commit ae02ae5
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 13 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changelog

## 0.7.1

### Bug Fixes
* Prevent index out of range panics when passenger processes are killed.

## 0.7.0

* Change group to `nobody` instead of `nogroup`.
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.5.1
0.7.1
15 changes: 12 additions & 3 deletions passenger_exporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ func (e *Exporter) Collect(ch chan<- prometheus.Metric) {
ch <- prometheus.MustNewConstMetric(e.appProcsSpawning, prometheus.GaugeValue, parseFloat(sg.Group.ProcessesSpawning), sg.Name)

// Update process identifiers map.
processIdentifiers = updateProcesses(processIdentifiers, sg.Group.Processes)
processIdentifiers = updateProcesses(processIdentifiers, sg.Group.Processes, parseInt(info.MaxProcessCount))
for _, proc := range sg.Group.Processes {
if bucketID, ok := processIdentifiers[proc.PID]; ok {
ch <- prometheus.MustNewConstMetric(e.procMemory, prometheus.GaugeValue, parseFloat(proc.RealMemory), sg.Name, strconv.Itoa(bucketID))
Expand Down Expand Up @@ -345,6 +345,15 @@ func parseFloat(val string) float64 {
return v
}

func parseInt(val string) int {
v, err := strconv.Atoi(val)
if err != nil {
log.Errorf("failed to parse %s: %v", val, err)
v = 0
}
return v
}

// updateProcesses updates the global map from process id:exporter id. Process
// TTLs cause new processes to be created on a user-defined cycle. When a new
// process replaces an old process, the new process's statistics will be
Expand All @@ -356,10 +365,10 @@ func parseFloat(val string) float64 {
// process/pid appears, it is mapped to either the first empty place
// within the global map storing process identifiers, or mapped to
// pid:id pair in the map.
func updateProcesses(old map[string]int, processes []Process) map[string]int {
func updateProcesses(old map[string]int, processes []Process, maxProcesses int) map[string]int {
var (
updated = make(map[string]int)
found = make([]string, len(old))
found = make([]string, maxProcesses)
missing []string
)

Expand Down
52 changes: 43 additions & 9 deletions passenger_exporter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,23 +115,26 @@ func TestStatusTimeout(t *testing.T) {
}

type updateProcessSpec struct {
name string
input map[string]int
processes []Process
output map[string]int
name string
input map[string]int
processes []Process
maxProcesses int
output map[string]int
}

func newUpdateProcessSpec(
name string,
input map[string]int,
processes []Process,
maxProcesses int,
) updateProcessSpec {
s := updateProcessSpec{
name: name,
input: input,
processes: processes,
name: name,
input: input,
processes: processes,
maxProcesses: maxProcesses,
}
s.output = updateProcesses(s.input, s.processes)
s.output = updateProcesses(s.input, s.processes, s.maxProcesses)
return s
}

Expand All @@ -145,6 +148,7 @@ func TestUpdateProcessIdentifiers(t *testing.T) {
Process{PID: "cdf"},
Process{PID: "dfe"},
},
3,
),
newUpdateProcessSpec(
"1:1",
Expand All @@ -158,6 +162,7 @@ func TestUpdateProcessIdentifiers(t *testing.T) {
Process{PID: "cdf"},
Process{PID: "dfe"},
},
6,
),
newUpdateProcessSpec(
"increase processes",
Expand All @@ -174,6 +179,7 @@ func TestUpdateProcessIdentifiers(t *testing.T) {
Process{PID: "jkl"},
Process{PID: "lmn"},
},
9,
),
newUpdateProcessSpec(
"reduce processes",
Expand All @@ -190,6 +196,33 @@ func TestUpdateProcessIdentifiers(t *testing.T) {
Process{PID: "cdf"},
Process{PID: "dfe"},
},
6,
),
newUpdateProcessSpec(
"first process killed",
map[string]int{
"abc": 0,
"cdf": 1,
"dfe": 2,
},
[]Process{
Process{PID: "cdf"},
Process{PID: "dfe"},
},
3,
),
newUpdateProcessSpec(
"second process killed",
map[string]int{
"abc": 0,
"cdf": 1,
"dfe": 2,
},
[]Process{
Process{PID: "abc"},
Process{PID: "dfe"},
},
3,
),
} {
if len(spec.output) != len(spec.processes) {
Expand All @@ -202,7 +235,7 @@ func TestUpdateProcessIdentifiers(t *testing.T) {
}
}

newOutput := updateProcesses(spec.output, spec.processes)
newOutput := updateProcesses(spec.output, spec.processes, spec.maxProcesses)
if !reflect.DeepEqual(newOutput, spec.output) {
t.Fatalf("case %s: updateProcesses is not idempotent", spec.name)
}
Expand All @@ -224,6 +257,7 @@ func TestInsertingNewProcesses(t *testing.T) {
Process{PID: "newPID"},
Process{PID: "newPID2"},
},
6,
)

if len(spec.output) != len(spec.processes) {
Expand Down

0 comments on commit ae02ae5

Please sign in to comment.