-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #9 from sergeymakinen/v2
Prepare v2
- Loading branch information
Showing
13 changed files
with
443 additions
and
116 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
# Postfix exporter configuration | ||
|
||
The file is written in [YAML format](http://en.wikipedia.org/wiki/YAML), defined by the scheme described below. | ||
Brackets indicate that a parameter is optional. | ||
For non-list parameters the value is set to the specified default. | ||
|
||
Generic placeholders are defined as follows: | ||
|
||
* `<string>`: a regular string | ||
* `<regex>`: a regular expression (see https://golang.org/s/re2syntax) | ||
|
||
The other placeholders are specified separately. | ||
|
||
See [postfix.yml](exporter/testdata/postfix.yml) for configuration examples. | ||
|
||
```yml | ||
host_replies: | ||
[ - <host_reply>, ... ] | ||
noqueue_reject_replies: | ||
[ - <noqueue_reject_reply>, ... ] | ||
``` | ||
|
||
### `<host_reply>` | ||
|
||
Example log entry for `queue_status`: | ||
|
||
``` | ||
Jan 1 00:00:00 hostname postfix/smtp[12345]: 123456789AB: to=<user@example.com>, relay=example.com[123.45.67.89]:25, delay=1.23, delays=1.23/1.23/1.23/1.23, dsn=1.2.3, status=bounced (host example.com[123.45.67.89] said: 123 #1.2.3 Reasons (in reply to end of DATA command)) | ||
``` | ||
|
||
Example log entry for `other`: | ||
|
||
``` | ||
Jan 1 00:00:00 hostname postfix/smtp[12345]: 123456789AB: host example.com[123.45.67.89] said: 123 1.2.3 Reasons (in reply to RCPT TO command) | ||
``` | ||
|
||
In both cases: | ||
|
||
* `123` is a status code | ||
* `1.2.3` is an enhanced status code | ||
* `Reasons` is the text of the reply | ||
|
||
```yml | ||
# The type of the reply. Accepted values: any, queue_status, other. | ||
[ type: <string> | default = "any" ] | ||
|
||
# The regular expression matching the reply text. | ||
regexp: <regex> | ||
|
||
# The replacement text (may include placeholders supported by Go, see https://pkg.go.dev/regexp#Regexp.Expand). | ||
text: <string> | ||
``` | ||
|
||
### `<noqueue_reject_replies>` | ||
|
||
Example log entry: | ||
|
||
``` | ||
Jan 1 00:00:00 hostname postfix/smtpd[12345]: NOQUEUE: reject: RCPT from example.com[123.45.67.89]: 123 1.2.3 <user@example.com>: Reasons; from=<user@example.com> to=<user@example.com> proto=ESMTP helo=<example.com> | ||
``` | ||
|
||
In this case: | ||
|
||
* `123` is a status code | ||
* `1.2.3` is an enhanced status code | ||
* `Reasons` is the text of the reply | ||
|
||
```yml | ||
# The regular expression matching the reply text. | ||
regexp: <regex> | ||
|
||
# The replacement text (may include placeholders supported by Go, see https://pkg.go.dev/regexp#Regexp.Expand). | ||
text: <string> | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
package config | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
"os" | ||
"regexp" | ||
|
||
"gopkg.in/yaml.v3" | ||
) | ||
|
||
type Config struct { | ||
HostReplies []HostReplyConfig `yaml:"host_replies,omitempty"` | ||
NoqueueRejectReplies []NoqueueRejectReplyConfig `yaml:"noqueue_reject_replies,omitempty"` | ||
} | ||
|
||
func Load(name string) (*Config, error) { | ||
f, err := os.Open(name) | ||
if err != nil { | ||
return nil, fmt.Errorf("error reading config file: %v", err) | ||
} | ||
defer f.Close() | ||
d := yaml.NewDecoder(f) | ||
d.KnownFields(true) | ||
var cfg Config | ||
if err = d.Decode(&cfg); err != nil { | ||
return nil, fmt.Errorf("error parsing config file: %v", err) | ||
} | ||
return &cfg, nil | ||
} | ||
|
||
type HostReplyConfig struct { | ||
Type HostReplyType `yaml:"type,omitempty"` | ||
Regexp *Regexp `yaml:"regexp"` | ||
Text string `yaml:"text"` | ||
} | ||
|
||
func (cfg *HostReplyConfig) UnmarshalYAML(value *yaml.Node) error { | ||
type plain HostReplyConfig | ||
if err := value.Decode((*plain)(cfg)); err != nil { | ||
return err | ||
} | ||
if cfg.Text == "" { | ||
return errors.New("empty text replacement") | ||
} | ||
return nil | ||
} | ||
|
||
type HostReplyType int | ||
|
||
func (t *HostReplyType) UnmarshalYAML(value *yaml.Node) error { | ||
var s string | ||
if err := value.Decode(&s); err != nil { | ||
return err | ||
} | ||
switch s { | ||
case "", "any": | ||
*t = HostReplyAny | ||
case "queue_status": | ||
*t = HostReplyQueueStatus | ||
case "other": | ||
*t = HostReplyOther | ||
default: | ||
return fmt.Errorf("unsupported host reply type %q", s) | ||
} | ||
return nil | ||
} | ||
|
||
// HostReplyType types. | ||
const ( | ||
HostReplyAny HostReplyType = iota | ||
HostReplyQueueStatus | ||
HostReplyOther | ||
) | ||
|
||
type NoqueueRejectReplyConfig struct { | ||
Regexp *Regexp `yaml:"regexp"` | ||
Text string `yaml:"text"` | ||
} | ||
|
||
func (cfg *NoqueueRejectReplyConfig) UnmarshalYAML(value *yaml.Node) error { | ||
type plain NoqueueRejectReplyConfig | ||
if err := value.Decode((*plain)(cfg)); err != nil { | ||
return err | ||
} | ||
if cfg.Text == "" { | ||
return errors.New("empty text replacement") | ||
} | ||
return nil | ||
} | ||
|
||
type Regexp struct { | ||
*regexp.Regexp | ||
} | ||
|
||
func (r *Regexp) UnmarshalYAML(value *yaml.Node) error { | ||
var s string | ||
if err := value.Decode(&s); err != nil { | ||
return err | ||
} | ||
re, err := regexp.Compile(s) | ||
if err != nil { | ||
return err | ||
} | ||
*r = Regexp{re} | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.