Advertisement
Guest User

Icecast collector

a guest
Mar 8th, 2017
136
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Go 3.74 KB | None | 0 0
  1. package icecast
  2.  
  3. import (
  4.     "fmt"
  5.   "net/http"
  6.     "encoding/xml"
  7.     "io/ioutil"
  8.     "log"
  9.  
  10.     "github.com/influxdata/telegraf"
  11.     "github.com/influxdata/telegraf/internal/errchan"
  12.     "github.com/influxdata/telegraf/plugins/inputs"
  13. )
  14.  
  15. // Icecast is an icecast plugin
  16. type Icecast struct {
  17.     Host            string
  18.     Username        string
  19.     Password        string
  20.     Alias               string
  21. }
  22.  
  23. // SourceListmounts holds single listener elements from Icecast XML
  24. type SourceListmounts struct {
  25.     Mount           string      `xml:"mount,attr"`
  26.     Listeners       int32       `xml:"listeners"`
  27.     Connected       int32       `xml:"connected"`
  28.     ContentType     string      `xml:"content-type"`
  29. }
  30.  
  31. // Listmounts main structure of icecast XML
  32. type Listmounts struct {
  33.     Sources []SourceListmounts `xml:"source"`
  34. }
  35.  
  36. var sampleConfig = `
  37.   ## Specify the IP adress to where the listmounts can be found. You can include port if needed.
  38.   host = ["localhost"]
  39.  
  40.   ## The username/password combination needed to read the listmounts page.
  41.   ## These must be equal to the admin login details specified in your Icecast configuration
  42.   username = ["admin"]
  43.   password = ["hackme"]
  44.  
  45.   ## If you wish your host name to be different then the one specified under host, you can change it here
  46.   alias = ["Radio"]
  47. `
  48. // Description returns description of Icecast plugin
  49. func (ice *Icecast) Description() string {
  50.     return "Read listeners from an Icecast instance"
  51. }
  52.  
  53. // The list of metrics that should be sent
  54. var sendMetrics = []string{
  55.     "listeners",
  56.     "host",
  57.     "mount",
  58. }
  59.  
  60. // SampleConfig returns sample configuration message
  61. func (ice *Icecast) SampleConfig() string {
  62.     return sampleConfig
  63. }
  64.  
  65. // Gather reads stats from all configured servers mount stats
  66. func (ice *Icecast) Gather(acc telegraf.Accumulator) error {
  67.   errChan := errchan.New(len(ice.Host))
  68.  
  69.   // Check to see if the needed fields are filled in, and if so, connect.
  70.   if len(ice.Host) != 0 && len(ice.Username) != 0 && len(ice.Password) != 0 {
  71.     errChan.C <- ice.gatherServer(ice.Host, ice.Username , ice.Password, ice.Alias, acc)
  72.   }
  73.  
  74.     return errChan.Error()
  75. }
  76.  
  77. func (ice *Icecast) gatherServer(
  78.     host string,
  79.     username string,
  80.   password string,
  81.   alias string,
  82.     acc telegraf.Accumulator,
  83. ) error {
  84.  
  85.     var err error
  86.   var listmounts Listmounts
  87.     var total int32
  88.  
  89.   // Create HTTP client to fetch the listmounts stats
  90.   httpClientIcecast := &http.Client{}
  91.   req, err := http.NewRequest("GET", fmt.Sprintf("http://%s/admin/listmounts", host), nil)
  92.   if err != nil {
  93.     log.Fatal(err)
  94.   }
  95.   req.SetBasicAuth(username, password)
  96.  
  97.   // Starting the HTTP request
  98.   icecastResponse, err := httpClientIcecast.Do(req)
  99.   if icecastResponse == nil {
  100.     fmt.Errorf("No Icecast respose")
  101.   }
  102.   if err != nil {
  103.     fmt.Errorf("Unable to make HTTP request")
  104.   }
  105.   defer icecastResponse.Body.Close()
  106.  
  107.   // Processing XML response
  108.   if body, err := ioutil.ReadAll(icecastResponse.Body); err == nil {
  109.     if err := xml.Unmarshal(body, &listmounts); err != nil {
  110.       fmt.Errorf("Unable to parse XML")
  111.     }
  112.   } else {
  113.     fmt.Errorf("Unable to ready body")
  114.   }
  115.  
  116.   // Run trough each mountpoint
  117.   for _, sources := range listmounts.Sources {
  118.  
  119.     tags := map[string]string{
  120.       "host": host,
  121.       "mount": sources.Mount,
  122.     }
  123.     fields := map[string]interface{}{
  124.       "listeners":   sources.Listeners,
  125.     }
  126.         acc.AddFields("icecast", fields, tags)
  127.     total += sources.Listeners
  128.   }
  129.  
  130.   // Report total listeners as well
  131.   tags_total := map[string]string{
  132.     "host": host,
  133.     "mount": "total",
  134.   }
  135.   fields_total := map[string]interface{}{
  136.     "listeners":   total,
  137.   }
  138.  
  139.     acc.AddFields("icecast", fields_total, tags_total)
  140.     return nil
  141. }
  142.  
  143. func init() {
  144.     inputs.Add("icecast", func() telegraf.Input {
  145.         return &Icecast{}
  146.     })
  147. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement