1
0
mirror of https://blitiri.com.ar/repos/chasquid synced 2025-12-18 14:47:03 +00:00

Introduce expvar counters

This patch introduces expvar counters to chasquid and the queue
packages.

For now there's only a handful of counters, but they will be expanded in
future patches.
This commit is contained in:
Alberto Bertogli
2016-10-08 12:36:48 +01:00
parent 641406cede
commit c4e8b22fd0
3 changed files with 39 additions and 0 deletions

View File

@@ -3,6 +3,7 @@ package main
import ( import (
"bytes" "bytes"
"crypto/tls" "crypto/tls"
"expvar"
"flag" "flag"
"fmt" "fmt"
"io" "io"
@@ -14,6 +15,7 @@ import (
"os" "os"
"os/signal" "os/signal"
"path/filepath" "path/filepath"
"strconv"
"strings" "strings"
"syscall" "syscall"
"time" "time"
@@ -37,11 +39,19 @@ import (
"github.com/golang/glog" "github.com/golang/glog"
) )
// Command-line flags.
var ( var (
configDir = flag.String("config_dir", "/etc/chasquid", configDir = flag.String("config_dir", "/etc/chasquid",
"configuration directory") "configuration directory")
) )
// Exported variables.
var (
commandCount = expvar.NewMap("chasquid/smtpIn/commandCount")
responseCodeCount = expvar.NewMap("chasquid/smtpIn/responseCodeCount")
spfResultCount = expvar.NewMap("chasquid/smtpIn/spfResultCount")
)
func main() { func main() {
flag.Parse() flag.Parse()
@@ -476,6 +486,7 @@ loop:
break break
} }
commandCount.Add(cmd, 1)
if cmd == "AUTH" { if cmd == "AUTH" {
c.tr.Debugf("-> AUTH <redacted>") c.tr.Debugf("-> AUTH <redacted>")
} else { } else {
@@ -642,6 +653,8 @@ func (c *Conn) MAIL(params string) (code int, msg string) {
c.spfResult, c.spfError = spf.CheckHost( c.spfResult, c.spfError = spf.CheckHost(
tcp.IP, envelope.DomainOf(e.Address)) tcp.IP, envelope.DomainOf(e.Address))
c.tr.Debugf("SPF %v (%v)", c.spfResult, c.spfError) c.tr.Debugf("SPF %v (%v)", c.spfResult, c.spfError)
spfResultCount.Add(string(c.spfResult), 1)
// https://tools.ietf.org/html/rfc7208#section-8 // https://tools.ietf.org/html/rfc7208#section-8
// We opt not to fail on errors, to avoid accidents to prevent // We opt not to fail on errors, to avoid accidents to prevent
// delivery. // delivery.
@@ -964,6 +977,7 @@ func (c *Conn) readLine() (line string, err error) {
func (c *Conn) writeResponse(code int, msg string) error { func (c *Conn) writeResponse(code int, msg string) error {
defer c.tc.W.Flush() defer c.tc.W.Flush()
responseCodeCount.Add(strconv.Itoa(code), 1)
return writeResponse(c.tc.W, code, msg) return writeResponse(c.tc.W, code, msg)
} }

View File

@@ -2,6 +2,7 @@ package courier
import ( import (
"crypto/tls" "crypto/tls"
"expvar"
"flag" "flag"
"net" "net"
"os" "os"
@@ -29,6 +30,11 @@ var (
fakeMX = map[string]string{} fakeMX = map[string]string{}
) )
// Exported variables.
var (
tlsCount = expvar.NewMap("chasquid/smtpOut/tlsCount")
)
// SMTP delivers remote mail via outgoing SMTP. // SMTP delivers remote mail via outgoing SMTP.
type SMTP struct { type SMTP struct {
} }
@@ -91,6 +97,7 @@ retry:
// Unfortunately, many servers use self-signed certs, so if we // Unfortunately, many servers use self-signed certs, so if we
// fail verification we just try again without validating. // fail verification we just try again without validating.
if insecure { if insecure {
tlsCount.Add("tls:failed", 1)
return tr.Errorf("TLS error: %v", err), false return tr.Errorf("TLS error: %v", err), false
} }
@@ -101,10 +108,13 @@ retry:
if config.InsecureSkipVerify { if config.InsecureSkipVerify {
tr.Debugf("Insecure - using TLS, but cert does not match %s", mx) tr.Debugf("Insecure - using TLS, but cert does not match %s", mx)
tlsCount.Add("tls:insecure", 1)
} else { } else {
tlsCount.Add("tls:secure", 1)
tr.Debugf("Secure - using TLS") tr.Debugf("Secure - using TLS")
} }
} else { } else {
tlsCount.Add("plain", 1)
tr.Debugf("Insecure - NOT using TLS") tr.Debugf("Insecure - NOT using TLS")
} }

View File

@@ -9,6 +9,7 @@ import (
"context" "context"
"crypto/rand" "crypto/rand"
"encoding/base64" "encoding/base64"
"expvar"
"fmt" "fmt"
"os" "os"
"os/exec" "os/exec"
@@ -51,6 +52,14 @@ var (
errQueueFull = fmt.Errorf("Queue size too big, try again later") errQueueFull = fmt.Errorf("Queue size too big, try again later")
) )
// Exported variables.
var (
putCount = expvar.NewInt("chasquid/queue/putCount")
itemsWritten = expvar.NewInt("chasquid/queue/itemsWritten")
dsnQueued = expvar.NewInt("chasquid/queue/dsnQueued")
deliverAttempts = expvar.NewMap("chasquid/queue/deliverAttempts")
)
// Channel used to get random IDs for items in the queue. // Channel used to get random IDs for items in the queue.
var newID chan string var newID chan string
@@ -148,6 +157,7 @@ func (q *Queue) Put(hostname, from string, to []string, data []byte) (string, er
if q.Len() >= maxQueueSize { if q.Len() >= maxQueueSize {
return "", errQueueFull return "", errQueueFull
} }
putCount.Add(1)
item := &Item{ item := &Item{
Message: Message{ Message: Message{
@@ -272,6 +282,7 @@ func ItemFromFile(fname string) (*Item, error) {
func (item *Item) WriteTo(dir string) error { func (item *Item) WriteTo(dir string) error {
item.Lock() item.Lock()
defer item.Unlock() defer item.Unlock()
itemsWritten.Add(1)
var err error var err error
item.CreatedAtTs, err = ptypes.TimestampProto(item.CreatedAt) item.CreatedAtTs, err = ptypes.TimestampProto(item.CreatedAt)
@@ -394,12 +405,14 @@ func sendDSN(tr *trace.Trace, q *Queue, item *Item) {
} }
tr.Printf("queued DSN: %s", id) tr.Printf("queued DSN: %s", id)
dsnQueued.Add(1)
} }
// deliver the item to the given recipient, using the couriers from the queue. // deliver the item to the given recipient, using the couriers from the queue.
// Return an error (if any), and whether it is permanent or not. // Return an error (if any), and whether it is permanent or not.
func (item *Item) deliver(q *Queue, rcpt *Recipient) (err error, permanent bool) { func (item *Item) deliver(q *Queue, rcpt *Recipient) (err error, permanent bool) {
if rcpt.Type == Recipient_PIPE { if rcpt.Type == Recipient_PIPE {
deliverAttempts.Add("pipe", 1)
c := strings.Fields(rcpt.Address) c := strings.Fields(rcpt.Address)
if len(c) == 0 { if len(c) == 0 {
return fmt.Errorf("empty pipe"), true return fmt.Errorf("empty pipe"), true
@@ -413,8 +426,10 @@ func (item *Item) deliver(q *Queue, rcpt *Recipient) (err error, permanent bool)
} else { } else {
if envelope.DomainIn(rcpt.Address, q.localDomains) { if envelope.DomainIn(rcpt.Address, q.localDomains) {
deliverAttempts.Add("email:local", 1)
return q.localC.Deliver(item.From, rcpt.Address, item.Data) return q.localC.Deliver(item.From, rcpt.Address, item.Data)
} else { } else {
deliverAttempts.Add("email:remote", 1)
from := item.From from := item.From
if !envelope.DomainIn(item.From, q.localDomains) { if !envelope.DomainIn(item.From, q.localDomains) {
// We're sending from a non-local to a non-local. This should // We're sending from a non-local to a non-local. This should