{"action":"created","issue":{"url":"https://api.github.com/repos/influxdata/telegraf/issues/502","labels_url":"https://api.github.com/repos/influxdata/telegraf/issues/502/labels{/name}","comments_url":"https://api.github.com/repos/influxdata/telegraf/issues/502/comments","events_url":"https://api.github.com/repos/influxdata/telegraf/issues/502/events","html_url":"https://github.com/influxdata/telegraf/issues/502","id":125848229,"number":502,"title":"phpfpm plugin doesn't return any data","user":{"login":"sofixa","id":4072680,"avatar_url":"https://avatars.githubusercontent.com/u/4072680?v=3","gravatar_id":"","url":"https://api.github.com/users/sofixa","html_url":"https://github.com/sofixa","followers_url":"https://api.github.com/users/sofixa/followers","following_url":"https://api.github.com/users/sofixa/following{/other_user}","gists_url":"https://api.github.com/users/sofixa/gists{/gist_id}","starred_url":"https://api.github.com/users/sofixa/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sofixa/subscriptions","organizations_url":"https://api.github.com/users/sofixa/orgs","repos_url":"https://api.github.com/users/sofixa/repos","events_url":"https://api.github.com/users/sofixa/events{/privacy}","received_events_url":"https://api.github.com/users/sofixa/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":5,"created_at":"2016-01-10T21:53:54Z","updated_at":"2016-01-14T18:49:01Z","closed_at":null,"body":"I have tried using the phpfpm plugin, and altough it runs successfully, it doesn't return any data. \r\nHere's the output from the command:\r\n```\r\n~$ /opt/telegraf/telegraf -config /etc/opt/telegraf/telegraf.conf -test -debug -filter phpfpm\r\n```\r\n\r\n```\r\n* Plugin: phpfpm, Collection 1\r\n```\r\n\r\nWithout -test i have:\r\n```\r\n2016/01/10 21:46:30 Gathered metrics, ({30s} interval), from 1 plugins in 13.174625ms\r\n```\r\n\r\nSo, in theory, it should work, but in InfluxDB i have absolutely nothing.\r\nPHP-FPM is working, and i have used it, and when running a script that shows the status of PHP-FPM i get plenty of data:\r\n\r\n```\r\n~# ./phpfpmstatus.sh /var/run/php5-fpm.sock\r\nX-Powered-By: PHP/5.5.9-1ubuntu4.14\r\nExpires: Thu, 01 Jan 1970 00:00:00 GMT\r\nCache-Control: no-cache, no-store, must-revalidate, max-age=0\r\nContent-Type: text/plain\r\n\r\npool:                 www\r\nprocess manager:      dynamic\r\nstart time:           10/Jan/2016:21:50:58 +0000\r\nstart since:          111\r\naccepted conn:        15\r\nlisten queue:         0\r\nmax listen queue:     0\r\nlisten queue len:     0\r\nidle processes:       1\r\nactive processes:     1\r\ntotal processes:      2\r\nmax active processes: 2\r\nmax children reached: 0\r\nslow requests:        0\r\n```\r\n\r\nWhat could be the problem? What metrics should the phpfpm plugin collect?"},"comment":{"url":"https://api.github.com/repos/influxdata/telegraf/issues/comments/171736413","html_url":"https://github.com/influxdata/telegraf/issues/502#issuecomment-171736413","issue_url":"https://api.github.com/repos/influxdata/telegraf/issues/502","id":171736413,"user":{"login":"kureikain","id":49754,"avatar_url":"https://avatars.githubusercontent.com/u/49754?v=3","gravatar_id":"","url":"https://api.github.com/users/kureikain","html_url":"https://github.com/kureikain","followers_url":"https://api.github.com/users/kureikain/followers","following_url":"https://api.github.com/users/kureikain/following{/other_user}","gists_url":"https://api.github.com/users/kureikain/gists{/gist_id}","starred_url":"https://api.github.com/users/kureikain/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kureikain/subscriptions","organizations_url":"https://api.github.com/users/kureikain/orgs","repos_url":"https://api.github.com/users/kureikain/repos","events_url":"https://api.github.com/users/kureikain/events{/privacy}","received_events_url":"https://api.github.com/users/kureikain/received_events","type":"User","site_admin":false},"created_at":"2016-01-14T18:49:01Z","updated_at":"2016-01-14T18:49:01Z","body":"@lassizci fcgi ideally should works. I don't write that part of code. Will look into it. Thanks for your Nginx configuration to limit access.\r\n\r\n@sofixa As @lassizci  pointed out, you can use `deny all` and `allow` before it to allow access from some ip such as 127.0.0.1.\r\n\r\n> Note:without the localhost: bit i was getting an error, which wasn't due to a rights issue, since i have been running my sock as 666.\r\n\r\nWill push a fix for this.\r\n\r\nI still not sure why it won't work even when you run under root. Will you able to compile this file and run it, it will output some info, I probably should return those error report into the plugin itself.\r\n\r\nFile `main.go`:\r\n\r\nContent:\r\n\r\n```Go\r\npackage main\r\n\r\n// FastCGI client to request via socket\r\n\r\n// Copyright 2012 Junqing Tan <ivan@mysqlab.net> and The Go Authors\r\n// Use of this source code is governed by a BSD-style\r\n// Part of source code is from Go fcgi package\r\n\r\n// Fix bug: Can't recive more than 1 record untill FCGI_END_REQUEST 2012-09-15\r\n// By: wofeiwo\r\n\r\nimport (\r\n\t\"bufio\"\r\n\t\"bytes\"\r\n\t\"encoding/binary\"\r\n\t\"errors\"\r\n\t\"io\"\r\n\t\"log\"\r\n\t\"net\"\r\n\t\"strconv\"\r\n\t\"sync\"\r\n)\r\n\r\nconst FCGI_LISTENSOCK_FILENO uint8 = 0\r\nconst FCGI_HEADER_LEN uint8 = 8\r\nconst VERSION_1 uint8 = 1\r\nconst FCGI_NULL_REQUEST_ID uint8 = 0\r\nconst FCGI_KEEP_CONN uint8 = 1\r\n\r\nconst (\r\n\tFCGI_BEGIN_REQUEST uint8 = iota + 1\r\n\tFCGI_ABORT_REQUEST\r\n\tFCGI_END_REQUEST\r\n\tFCGI_PARAMS\r\n\tFCGI_STDIN\r\n\tFCGI_STDOUT\r\n\tFCGI_STDERR\r\n\tFCGI_DATA\r\n\tFCGI_GET_VALUES\r\n\tFCGI_GET_VALUES_RESULT\r\n\tFCGI_UNKNOWN_TYPE\r\n\tFCGI_MAXTYPE = FCGI_UNKNOWN_TYPE\r\n)\r\n\r\nconst (\r\n\tFCGI_RESPONDER uint8 = iota + 1\r\n\tFCGI_AUTHORIZER\r\n\tFCGI_FILTER\r\n)\r\n\r\nconst (\r\n\tFCGI_REQUEST_COMPLETE uint8 = iota\r\n\tFCGI_CANT_MPX_CONN\r\n\tFCGI_OVERLOADED\r\n\tFCGI_UNKNOWN_ROLE\r\n)\r\n\r\nconst (\r\n\tFCGI_MAX_CONNS  string = \"MAX_CONNS\"\r\n\tFCGI_MAX_REQS   string = \"MAX_REQS\"\r\n\tFCGI_MPXS_CONNS string = \"MPXS_CONNS\"\r\n)\r\n\r\nconst (\r\n\tmaxWrite = 6553500 // maximum record body\r\n\tmaxPad   = 255\r\n)\r\n\r\ntype header struct {\r\n\tVersion       uint8\r\n\tType          uint8\r\n\tId            uint16\r\n\tContentLength uint16\r\n\tPaddingLength uint8\r\n\tReserved      uint8\r\n}\r\n\r\n// for padding so we don't have to allocate all the time\r\n// not synchronized because we don't care what the contents are\r\nvar pad [maxPad]byte\r\n\r\nfunc (h *header) init(recType uint8, reqId uint16, contentLength int) {\r\n\th.Version = 1\r\n\th.Type = recType\r\n\th.Id = reqId\r\n\th.ContentLength = uint16(contentLength)\r\n\th.PaddingLength = uint8(-contentLength & 7)\r\n}\r\n\r\ntype record struct {\r\n\th   header\r\n\tbuf [maxWrite + maxPad]byte\r\n}\r\n\r\nfunc (rec *record) read(r io.Reader) (err error) {\r\n\tif err = binary.Read(r, binary.BigEndian, &rec.h); err != nil {\r\n\t\treturn err\r\n\t}\r\n\tif rec.h.Version != 1 {\r\n\t\treturn errors.New(\"fcgi: invalid header version\")\r\n\t}\r\n\tn := int(rec.h.ContentLength) + int(rec.h.PaddingLength)\r\n\tif _, err = io.ReadFull(r, rec.buf[:n]); err != nil {\r\n\t\treturn err\r\n\t}\r\n\treturn nil\r\n}\r\n\r\nfunc (r *record) content() []byte {\r\n\treturn r.buf[:r.h.ContentLength]\r\n}\r\n\r\ntype FCGIClient struct {\r\n\tmutex     sync.Mutex\r\n\trwc       io.ReadWriteCloser\r\n\th         header\r\n\tbuf       bytes.Buffer\r\n\tkeepAlive bool\r\n}\r\n\r\nfunc NewClient(h string, args ...interface{}) (fcgi *FCGIClient, err error) {\r\n\tvar conn net.Conn\r\n\tif len(args) != 1 {\r\n\t\terr = errors.New(\"fcgi: not enough params\")\r\n\t\treturn\r\n\t}\r\n\tswitch args[0].(type) {\r\n\tcase int:\r\n\t\taddr := h + \":\" + strconv.FormatInt(int64(args[0].(int)), 10)\r\n\t\tconn, err = net.Dial(\"tcp\", addr)\r\n\tcase string:\r\n\t\tladdr := net.UnixAddr{Name: args[0].(string), Net: h}\r\n\t\tconn, err = net.DialUnix(h, nil, &laddr)\r\n\tdefault:\r\n\t\terr = errors.New(\"fcgi: we only accept int (port) or string (socket) params.\")\r\n\t}\r\n\tfcgi = &FCGIClient{\r\n\t\trwc:       conn,\r\n\t\tkeepAlive: false,\r\n\t}\r\n\treturn\r\n}\r\n\r\nfunc (client *FCGIClient) writeRecord(recType uint8, reqId uint16, content []byte) (err error) {\r\n\tclient.mutex.Lock()\r\n\tdefer client.mutex.Unlock()\r\n\tclient.buf.Reset()\r\n\tclient.h.init(recType, reqId, len(content))\r\n\tif err := binary.Write(&client.buf, binary.BigEndian, client.h); err != nil {\r\n\t\treturn err\r\n\t}\r\n\tif _, err := client.buf.Write(content); err != nil {\r\n\t\treturn err\r\n\t}\r\n\tif _, err := client.buf.Write(pad[:client.h.PaddingLength]); err != nil {\r\n\t\treturn err\r\n\t}\r\n\t_, err = client.rwc.Write(client.buf.Bytes())\r\n\treturn err\r\n}\r\n\r\nfunc (client *FCGIClient) writeBeginRequest(reqId uint16, role uint16, flags uint8) error {\r\n\tb := [8]byte{byte(role >> 8), byte(role), flags}\r\n\treturn client.writeRecord(FCGI_BEGIN_REQUEST, reqId, b[:])\r\n}\r\n\r\nfunc (client *FCGIClient) writeEndRequest(reqId uint16, appStatus int, protocolStatus uint8) error {\r\n\tb := make([]byte, 8)\r\n\tbinary.BigEndian.PutUint32(b, uint32(appStatus))\r\n\tb[4] = protocolStatus\r\n\treturn client.writeRecord(FCGI_END_REQUEST, reqId, b)\r\n}\r\n\r\nfunc (client *FCGIClient) writePairs(recType uint8, reqId uint16, pairs map[string]string) error {\r\n\tw := newWriter(client, recType, reqId)\r\n\tb := make([]byte, 8)\r\n\tfor k, v := range pairs {\r\n\t\tn := encodeSize(b, uint32(len(k)))\r\n\t\tn += encodeSize(b[n:], uint32(len(v)))\r\n\t\tif _, err := w.Write(b[:n]); err != nil {\r\n\t\t\treturn err\r\n\t\t}\r\n\t\tif _, err := w.WriteString(k); err != nil {\r\n\t\t\treturn err\r\n\t\t}\r\n\t\tif _, err := w.WriteString(v); err != nil {\r\n\t\t\treturn err\r\n\t\t}\r\n\t}\r\n\tw.Close()\r\n\treturn nil\r\n}\r\n\r\nfunc readSize(s []byte) (uint32, int) {\r\n\tif len(s) == 0 {\r\n\t\treturn 0, 0\r\n\t}\r\n\tsize, n := uint32(s[0]), 1\r\n\tif size&(1<<7) != 0 {\r\n\t\tif len(s) < 4 {\r\n\t\t\treturn 0, 0\r\n\t\t}\r\n\t\tn = 4\r\n\t\tsize = binary.BigEndian.Uint32(s)\r\n\t\tsize &^= 1 << 31\r\n\t}\r\n\treturn size, n\r\n}\r\n\r\nfunc readString(s []byte, size uint32) string {\r\n\tif size > uint32(len(s)) {\r\n\t\treturn \"\"\r\n\t}\r\n\treturn string(s[:size])\r\n}\r\n\r\nfunc encodeSize(b []byte, size uint32) int {\r\n\tif size > 127 {\r\n\t\tsize |= 1 << 31\r\n\t\tbinary.BigEndian.PutUint32(b, size)\r\n\t\treturn 4\r\n\t}\r\n\tb[0] = byte(size)\r\n\treturn 1\r\n}\r\n\r\n// bufWriter encapsulates bufio.Writer but also closes the underlying stream when\r\n// Closed.\r\ntype bufWriter struct {\r\n\tcloser io.Closer\r\n\t*bufio.Writer\r\n}\r\n\r\nfunc (w *bufWriter) Close() error {\r\n\tif err := w.Writer.Flush(); err != nil {\r\n\t\tw.closer.Close()\r\n\t\treturn err\r\n\t}\r\n\treturn w.closer.Close()\r\n}\r\n\r\nfunc newWriter(c *FCGIClient, recType uint8, reqId uint16) *bufWriter {\r\n\ts := &streamWriter{c: c, recType: recType, reqId: reqId}\r\n\tw := bufio.NewWriterSize(s, maxWrite)\r\n\treturn &bufWriter{s, w}\r\n}\r\n\r\n// streamWriter abstracts out the separation of a stream into discrete records.\r\n// It only writes maxWrite bytes at a time.\r\ntype streamWriter struct {\r\n\tc       *FCGIClient\r\n\trecType uint8\r\n\treqId   uint16\r\n}\r\n\r\nfunc (w *streamWriter) Write(p []byte) (int, error) {\r\n\tnn := 0\r\n\tfor len(p) > 0 {\r\n\t\tn := len(p)\r\n\t\tif n > maxWrite {\r\n\t\t\tn = maxWrite\r\n\t\t}\r\n\t\tif err := w.c.writeRecord(w.recType, w.reqId, p[:n]); err != nil {\r\n\t\t\treturn nn, err\r\n\t\t}\r\n\t\tnn += n\r\n\t\tp = p[n:]\r\n\t}\r\n\treturn nn, nil\r\n}\r\n\r\nfunc (w *streamWriter) Close() error {\r\n\t// send empty record to close the stream\r\n\treturn w.c.writeRecord(w.recType, w.reqId, nil)\r\n}\r\n\r\nfunc (client *FCGIClient) Request(env map[string]string, reqStr string) (retout []byte, reterr []byte, err error) {\r\n\r\n\tvar reqId uint16 = 1\r\n\tdefer client.rwc.Close()\r\n\r\n\terr = client.writeBeginRequest(reqId, uint16(FCGI_RESPONDER), 0)\r\n\tif err != nil {\r\n\t\treturn\r\n\t}\r\n\terr = client.writePairs(FCGI_PARAMS, reqId, env)\r\n\tif err != nil {\r\n\t\treturn\r\n\t}\r\n\tif len(reqStr) > 0 {\r\n\t\terr = client.writeRecord(FCGI_STDIN, reqId, []byte(reqStr))\r\n\t\tif err != nil {\r\n\t\t\treturn\r\n\t\t}\r\n\t}\r\n\r\n\trec := &record{}\r\n\tvar err1 error\r\n\r\n\t// recive untill EOF or FCGI_END_REQUEST\r\n\tfor {\r\n\t\terr1 = rec.read(client.rwc)\r\n\t\tif err1 != nil {\r\n\t\t\tif err1 != io.EOF {\r\n\t\t\t\terr = err1\r\n\t\t\t}\r\n\t\t\tbreak\r\n\t\t}\r\n\t\tswitch {\r\n\t\tcase rec.h.Type == FCGI_STDOUT:\r\n\t\t\tretout = append(retout, rec.content()...)\r\n\t\tcase rec.h.Type == FCGI_STDERR:\r\n\t\t\treterr = append(reterr, rec.content()...)\r\n\t\tcase rec.h.Type == FCGI_END_REQUEST:\r\n\t\t\tfallthrough\r\n\t\tdefault:\r\n\t\t\tbreak\r\n\t\t}\r\n\t}\r\n\r\n\treturn\r\n}\r\n\r\nfunc main() {\r\n\tfcgi, _ := NewClient(\"unix\", \"/var/run/php5-fpm.sock\")\r\n\tresOut, resErr, err := fcgi.Request(map[string]string{\r\n\t\t\"SCRIPT_NAME\":     \"/status\",\r\n\t\t\"SCRIPT_FILENAME\": \"status\",\r\n\t\t\"REQUEST_METHOD\":  \"GET\",\r\n\t}, \"\")\r\n\r\n\tlog.Printf(\"Output: %v\\n\", string(resOut))\r\n\tlog.Printf(\"Sock Err: %v\\n\", string(resErr))\r\n\tlog.Printf(\"Err: %v\\n\", err)\r\n}\r\n```\r\n\r\nAnd run it:\r\n\r\n```\r\ngo run main.go\r\n```\r\n\r\nMaybe we can find something about it. I will submit a PRs to make the plugin return error information so Telegraf can log the in its log."}}