Skip to content

Commit

Permalink
fix: json: cannot unmarshal number (#28)
Browse files Browse the repository at this point in the history
* fixes #26
* better comments & fix tests
  • Loading branch information
XooR authored and estahn committed Jun 26, 2018
1 parent 2ff0145 commit 03d8708
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 14 deletions.
47 changes: 34 additions & 13 deletions phpfpm/phpfpm.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,21 +84,23 @@ type Pool struct {
Processes []PoolProcess `json:"processes"`
}

type requestDuration int64

// PoolProcess describes a single PHP-FPM process. A pool can have multiple processes.
type PoolProcess struct {
PID int64 `json:"pid"`
State string `json:"state"`
StartTime int64 `json:"start time"`
StartSince int64 `json:"start since"`
Requests int64 `json:"requests"`
RequestDuration int64 `json:"request duration"`
RequestMethod string `json:"request method"`
RequestURI string `json:"request uri"`
ContentLength int64 `json:"content length"`
User string `json:"user"`
Script string `json:"script"`
LastRequestCPU float64 `json:"last request cpu"`
LastRequestMemory int64 `json:"last request memory"`
PID int64 `json:"pid"`
State string `json:"state"`
StartTime int64 `json:"start time"`
StartSince int64 `json:"start since"`
Requests int64 `json:"requests"`
RequestDuration requestDuration `json:"request duration"`
RequestMethod string `json:"request method"`
RequestURI string `json:"request uri"`
ContentLength int64 `json:"content length"`
User string `json:"user"`
Script string `json:"script"`
LastRequestCPU float64 `json:"last request cpu"`
LastRequestMemory int64 `json:"last request memory"`
}

// PoolProcessStateCounter holds the calculated metrics for pool processes.
Expand Down Expand Up @@ -257,6 +259,25 @@ func (t *timestamp) UnmarshalJSON(b []byte) error {
return nil
}

// This is because of bug in php-fpm that can return 'request duration' which can't
// fit to int64. For details check links:
// https://bugs.php.net/bug.php?id=62382
// https://serverfault.com/questions/624977/huge-request-duration-value-for-a-particular-php-script
func (rd *requestDuration) MarshalJSON() ([]byte, error) {
stamp := fmt.Sprint(rd)
return []byte(stamp), nil
}

func (rd *requestDuration) UnmarshalJSON(b []byte) error {
rdc, err := strconv.Atoi(string(b))
if err != nil {
*rd = 0
} else {
*rd = requestDuration(rdc)
}
return nil
}

// SetLogger configures the used logger
func SetLogger(logger logger) {
log = logger
Expand Down
4 changes: 3 additions & 1 deletion phpfpm/phpfpm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,9 @@ func TestCannotUnmarshalNumberIssue10(t *testing.T) {

err := json.Unmarshal(content, &pool)

assert.NotNil(t, err, err.Error())
assert.Nil(t, err, "successfully unmarshal on invalid 'request duration'")
assert.Equal(t, int(pool.Processes[0].RequestDuration), 295, "request duration set to 0 because it couldn't be deserialized")
assert.Equal(t, int(pool.Processes[1].RequestDuration), 0, "request duration set to 0 because it couldn't be deserialized")
}

func TestParseURL(t *testing.T) {
Expand Down

0 comments on commit 03d8708

Please sign in to comment.