112 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			112 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			Go
		
	
	
	
| package postfix
 | |
| 
 | |
| import (
 | |
| 	"fmt"
 | |
| 	"os"
 | |
| 	"os/exec"
 | |
| 	"path/filepath"
 | |
| 	"strings"
 | |
| 	"time"
 | |
| 
 | |
| 	"github.com/influxdata/telegraf"
 | |
| 	"github.com/influxdata/telegraf/plugins/inputs"
 | |
| )
 | |
| 
 | |
| const sampleConfig = `
 | |
|   ## Postfix queue directory. If not provided, telegraf will try to use
 | |
|   ## 'postconf -h queue_directory' to determine it.
 | |
|   # queue_directory = "/var/spool/postfix"
 | |
| `
 | |
| 
 | |
| const description = "Measure postfix queue statistics"
 | |
| 
 | |
| func getQueueDirectory() (string, error) {
 | |
| 	qd, err := exec.Command("postconf", "-h", "queue_directory").Output()
 | |
| 	if err != nil {
 | |
| 		return "", err
 | |
| 	}
 | |
| 	return strings.TrimSpace(string(qd)), nil
 | |
| }
 | |
| 
 | |
| func qScan(path string, acc telegraf.Accumulator) (int64, int64, int64, error) {
 | |
| 	var length, size int64
 | |
| 	var oldest time.Time
 | |
| 	err := filepath.Walk(path, func(_ string, finfo os.FileInfo, err error) error {
 | |
| 		if err != nil {
 | |
| 			acc.AddError(fmt.Errorf("error scanning %s: %s", path, err))
 | |
| 			return nil
 | |
| 		}
 | |
| 		if finfo.IsDir() {
 | |
| 			return nil
 | |
| 		}
 | |
| 
 | |
| 		length++
 | |
| 		size += finfo.Size()
 | |
| 
 | |
| 		ctime := statCTime(finfo.Sys())
 | |
| 		if ctime.IsZero() {
 | |
| 			return nil
 | |
| 		}
 | |
| 		if oldest.IsZero() || ctime.Before(oldest) {
 | |
| 			oldest = ctime
 | |
| 		}
 | |
| 		return nil
 | |
| 	})
 | |
| 	if err != nil {
 | |
| 		return 0, 0, 0, err
 | |
| 	}
 | |
| 	var age int64
 | |
| 	if !oldest.IsZero() {
 | |
| 		age = int64(time.Now().Sub(oldest) / time.Second)
 | |
| 	} else if length != 0 {
 | |
| 		// system doesn't support ctime
 | |
| 		age = -1
 | |
| 	}
 | |
| 	return length, size, age, nil
 | |
| }
 | |
| 
 | |
| type Postfix struct {
 | |
| 	QueueDirectory string
 | |
| }
 | |
| 
 | |
| func (p *Postfix) Gather(acc telegraf.Accumulator) error {
 | |
| 	if p.QueueDirectory == "" {
 | |
| 		var err error
 | |
| 		p.QueueDirectory, err = getQueueDirectory()
 | |
| 		if err != nil {
 | |
| 			return fmt.Errorf("unable to determine queue directory: %s", err)
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	for _, q := range []string{"active", "hold", "incoming", "maildrop", "deferred"} {
 | |
| 		length, size, age, err := qScan(filepath.Join(p.QueueDirectory, q), acc)
 | |
| 		if err != nil {
 | |
| 			acc.AddError(fmt.Errorf("error scanning queue %s: %s", q, err))
 | |
| 			continue
 | |
| 		}
 | |
| 		fields := map[string]interface{}{"length": length, "size": size}
 | |
| 		if age != -1 {
 | |
| 			fields["age"] = age
 | |
| 		}
 | |
| 		acc.AddFields("postfix_queue", fields, map[string]string{"queue": q})
 | |
| 	}
 | |
| 
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| func (p *Postfix) SampleConfig() string {
 | |
| 	return sampleConfig
 | |
| }
 | |
| 
 | |
| func (p *Postfix) Description() string {
 | |
| 	return description
 | |
| }
 | |
| 
 | |
| func init() {
 | |
| 	inputs.Add("postfix", func() telegraf.Input {
 | |
| 		return &Postfix{
 | |
| 			QueueDirectory: "/var/spool/postfix",
 | |
| 		}
 | |
| 	})
 | |
| }
 |