/* * SPDX-FileCopyrightText: 2020 Stalwart Labs Ltd * * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL */ pub mod atomics; pub mod event; pub mod ipc; pub mod macros; pub mod serializers; use std::{ net::{IpAddr, Ipv4Addr, Ipv6Addr}, sync::Arc, }; pub use crate::ipc::collector::Collector; pub use event_macro::event; use event_macro::{event_family, event_type, key_names, total_event_count}; pub type Result = std::result::Result; pub type Error = Event; #[derive(Debug, Clone)] pub struct Event { pub inner: T, pub keys: Vec<(Key, Value)>, } #[derive(Debug, Clone)] pub struct EventDetails { pub typ: EventType, pub timestamp: u64, pub level: Level, pub span: Option>>, } #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)] #[repr(usize)] pub enum Level { Trace = 0, Debug = 1, Info = 2, Warn = 3, Error = 4, Disable = 5, } #[derive(Debug, Default, Clone)] pub enum Value { Static(&'static str), String(String), UInt(u64), Int(i64), Float(f64), Timestamp(u64), Duration(u64), Bytes(Vec), Bool(bool), Ipv4(Ipv4Addr), Ipv6(Ipv6Addr), Event(Event), Array(Vec), #[default] None, } #[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)] #[key_names] pub enum Key { AccountName, AccountId, BlobId, #[default] CausedBy, ChangeId, Code, Collection, Contents, Details, DkimFail, DkimNone, DkimPass, DmarcNone, DmarcPass, DmarcQuarantine, DmarcReject, DocumentId, Domain, Due, Elapsed, Expires, From, Hostname, Id, Key, Limit, ListenerId, LocalIp, LocalPort, MailboxName, MailboxId, MessageId, NextDsn, NextRetry, Path, Policy, QueueId, RangeFrom, RangeTo, Reason, RemoteIp, RemotePort, ReportId, Result, Size, Source, SpanId, SpfFail, SpfNone, SpfPass, Strict, Tls, To, Total, TotalFailures, TotalSuccesses, Type, Uid, UidNext, UidValidity, Url, ValidFrom, ValidTo, Value, Version, } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[event_family] pub enum EventType { Server(ServerEvent), Purge(PurgeEvent), Eval(EvalEvent), Acme(AcmeEvent), Store(StoreEvent), MessageIngest(MessageIngestEvent), Jmap(JmapEvent), Imap(ImapEvent), ManageSieve(ManageSieveEvent), Pop3(Pop3Event), Smtp(SmtpEvent), Http(HttpEvent), Network(NetworkEvent), Limit(LimitEvent), Manage(ManageEvent), Auth(AuthEvent), Config(ConfigEvent), Resource(ResourceEvent), Arc(ArcEvent), Dkim(DkimEvent), Dmarc(DmarcEvent), Iprev(IprevEvent), Dane(DaneEvent), Spf(SpfEvent), MailAuth(MailAuthEvent), Tls(TlsEvent), Sieve(SieveEvent), Spam(SpamEvent), PushSubscription(PushSubscriptionEvent), Cluster(ClusterEvent), Housekeeper(HousekeeperEvent), FtsIndex(FtsIndexEvent), Milter(MilterEvent), MtaHook(MtaHookEvent), Delivery(DeliveryEvent), Queue(QueueEvent), TlsRpt(TlsRptEvent), MtaSts(MtaStsEvent), IncomingReport(IncomingReportEvent), OutgoingReport(OutgoingReportEvent), Telemetry(TelemetryEvent), Security(SecurityEvent), } #[event_type] pub enum HttpEvent { ConnectionStart, ConnectionEnd, Error, RequestUrl, RequestBody, ResponseBody, XForwardedMissing, } #[event_type] pub enum SecurityEvent { AuthenticationBan, BruteForceBan, LoiterBan, IpBlocked, } #[event_type] pub enum ClusterEvent { PeerAlive, PeerDiscovered, PeerOffline, PeerSuspected, PeerSuspectedIsAlive, PeerBackOnline, PeerLeaving, PeerHasConfigChanges, PeerHasListChanges, OneOrMorePeersOffline, EmptyPacket, InvalidPacket, DecryptionError, Error, } #[event_type] pub enum HousekeeperEvent { Start, Stop, Schedule, PurgeAccounts, PurgeSessions, PurgeStore, } #[event_type] pub enum FtsIndexEvent { Index, Locked, LockBusy, BlobNotFound, MetadataNotFound, } #[event_type] pub enum ImapEvent { ConnectionStart, ConnectionEnd, // Commands GetAcl, SetAcl, MyRights, ListRights, Append, Capabilities, Id, Close, Copy, Move, CreateMailbox, DeleteMailbox, RenameMailbox, Enable, Expunge, Fetch, IdleStart, IdleStop, List, Lsub, Logout, Namespace, Noop, Search, Sort, Select, Status, Store, Subscribe, Unsubscribe, Thread, // Errors Error, // Debugging RawInput, RawOutput, } #[event_type] pub enum Pop3Event { ConnectionStart, ConnectionEnd, // Commands Delete, Reset, Quit, Fetch, List, ListMessage, Uidl, UidlMessage, Stat, Noop, Capabilities, StartTls, Utf8, // Errors Error, // Debugging RawInput, RawOutput, } #[event_type] pub enum ManageSieveEvent { ConnectionStart, ConnectionEnd, // Commands CreateScript, UpdateScript, GetScript, DeleteScript, RenameScript, CheckScript, HaveSpace, ListScripts, SetActive, Capabilities, StartTls, Unauthenticate, Logout, Noop, // Errors Error, // Debugging RawInput, RawOutput, } #[event_type] pub enum SmtpEvent { ConnectionStart, ConnectionEnd, Error, RemoteIdNotFound, ConcurrencyLimitExceeded, TransferLimitExceeded, RateLimitExceeded, TimeLimitExceeded, MissingAuthDirectory, MessageParseFailed, MessageTooLarge, LoopDetected, PipeSuccess, PipeError, DkimPass, DkimFail, ArcPass, ArcFail, SpfEhloPass, SpfEhloFail, SpfFromPass, SpfFromFail, DmarcPass, DmarcFail, IprevPass, IprevFail, TooManyMessages, Ehlo, InvalidEhlo, DidNotSayEhlo, EhloExpected, LhloExpected, MailFromUnauthenticated, MailFromUnauthorized, MailFromNotAllowed, MailFromRewritten, MailFromMissing, MailFrom, MultipleMailFrom, MailboxDoesNotExist, RelayNotAllowed, RcptTo, RcptToDuplicate, RcptToRewritten, RcptToMissing, TooManyRecipients, TooManyInvalidRcpt, RawInput, RawOutput, MissingLocalHostname, Vrfy, VrfyNotFound, VrfyDisabled, Expn, ExpnNotFound, ExpnDisabled, RequireTlsDisabled, DeliverByDisabled, DeliverByInvalid, FutureReleaseDisabled, FutureReleaseInvalid, MtPriorityDisabled, MtPriorityInvalid, DsnDisabled, AuthNotAllowed, AuthMechanismNotSupported, AuthExchangeTooLong, AlreadyAuthenticated, Noop, StartTls, StartTlsUnavailable, StartTlsAlready, Rset, Quit, Help, CommandNotImplemented, InvalidCommand, InvalidSenderAddress, InvalidRecipientAddress, InvalidParameter, UnsupportedParameter, SyntaxError, RequestTooLarge, } #[event_type] pub enum DeliveryEvent { AttemptStart, AttemptEnd, Completed, Failed, DomainDeliveryStart, MxLookup, MxLookupFailed, IpLookup, IpLookupFailed, NullMx, Connect, ConnectError, MissingOutboundHostname, GreetingFailed, Ehlo, EhloRejected, Auth, AuthFailed, MailFrom, MailFromRejected, Delivered, RcptTo, RcptToRejected, RcptToFailed, MessageRejected, StartTls, StartTlsUnavailable, StartTlsError, StartTlsDisabled, ImplicitTlsError, ConcurrencyLimitExceeded, RateLimitExceeded, DoubleBounce, DsnSuccess, DsnTempFail, DsnPermFail, RawInput, RawOutput, } #[event_type] pub enum QueueEvent { QueueMessage, QueueMessageAuthenticated, QueueReport, QueueDsn, QueueAutogenerated, Rescheduled, LockBusy, Locked, BlobNotFound, RateLimitExceeded, ConcurrencyLimitExceeded, QuotaExceeded, } #[event_type] pub enum IncomingReportEvent { DmarcReport, DmarcReportWithWarnings, TlsReport, TlsReportWithWarnings, AbuseReport, AuthFailureReport, FraudReport, NotSpamReport, VirusReport, OtherReport, MessageParseFailed, DmarcParseFailed, TlsRpcParseFailed, ArfParseFailed, DecompressError, } #[event_type] pub enum OutgoingReportEvent { SpfReport, SpfRateLimited, DkimReport, DkimRateLimited, DmarcReport, DmarcRateLimited, DmarcAggregateReport, TlsAggregate, HttpSubmission, UnauthorizedReportingAddress, ReportingAddressValidationError, NotFound, SubmissionError, NoRecipientsFound, LockBusy, LockDeleted, Locked, } #[event_type] pub enum MtaStsEvent { Authorized, NotAuthorized, PolicyFetch, PolicyNotFound, PolicyFetchError, InvalidPolicy, } #[event_type] pub enum TlsRptEvent { RecordFetch, RecordFetchError, } #[event_type] pub enum DaneEvent { AuthenticationSuccess, AuthenticationFailure, NoCertificatesFound, CertificateParseError, TlsaRecordMatch, TlsaRecordFetch, TlsaRecordFetchError, TlsaRecordNotFound, TlsaRecordNotDnssecSigned, TlsaRecordInvalid, } #[event_type] pub enum MilterEvent { Read, Write, ActionAccept, ActionDiscard, ActionReject, ActionTempFail, ActionReplyCode, ActionConnectionFailure, ActionShutdown, IoError, FrameTooLarge, FrameInvalid, UnexpectedResponse, Timeout, TlsInvalidName, Disconnected, ParseError, } #[event_type] pub enum MtaHookEvent { ActionAccept, ActionDiscard, ActionReject, ActionQuarantine, Error, } #[event_type] pub enum PushSubscriptionEvent { Success, Error, NotFound, } #[event_type] pub enum SpamEvent { PyzorError, ListUpdated, Train, TrainBalance, TrainError, Classify, ClassifyError, NotEnoughTrainingData, } #[event_type] pub enum SieveEvent { ActionAccept, ActionAcceptReplace, ActionDiscard, ActionReject, SendMessage, MessageTooLarge, ScriptNotFound, ListNotFound, RuntimeError, UnexpectedError, NotSupported, QuotaExceeded, } #[event_type] pub enum TlsEvent { Handshake, HandshakeError, NotConfigured, CertificateNotFound, NoCertificatesAvailable, MultipleCertificatesAvailable, } #[event_type] pub enum NetworkEvent { ListenStart, ListenStop, ListenError, BindError, ReadError, WriteError, FlushError, AcceptError, SplitError, Timeout, Closed, ProxyError, SetOptError, } #[event_type] pub enum ServerEvent { Startup, Shutdown, StartupError, ThreadError, Licensing, } #[event_type] pub enum TelemetryEvent { Alert, LogError, WebhookError, OtelExporterError, OtelMetricsExporterError, PrometheusExporterError, JournalError, } #[event_type] pub enum AcmeEvent { AuthStart, AuthPending, AuthValid, AuthCompleted, AuthError, AuthTooManyAttempts, ProcessCert, OrderStart, OrderProcessing, OrderCompleted, OrderReady, OrderValid, OrderInvalid, RenewBackoff, DnsRecordCreated, DnsRecordCreationFailed, DnsRecordDeletionFailed, DnsRecordNotPropagated, DnsRecordLookupFailed, DnsRecordPropagated, DnsRecordPropagationTimeout, ClientSuppliedSni, ClientMissingSni, TlsAlpnReceived, TlsAlpnError, TokenNotFound, Error, } #[event_type] pub enum PurgeEvent { Started, Finished, Running, Error, PurgeActive, AutoExpunge, TombstoneCleanup, } #[event_type] pub enum EvalEvent { Result, Error, DirectoryNotFound, StoreNotFound, } #[event_type] pub enum ConfigEvent { ParseError, BuildError, MacroError, WriteError, FetchError, DefaultApplied, MissingSetting, UnusedSetting, ParseWarning, BuildWarning, ImportExternal, ExternalKeyIgnored, AlreadyUpToDate, } #[event_type] pub enum ArcEvent { ChainTooLong, InvalidInstance, InvalidCv, HasHeaderTag, BrokenChain, SealerNotFound, } #[event_type] pub enum DkimEvent { Pass, Neutral, Fail, PermError, TempError, None, UnsupportedVersion, UnsupportedAlgorithm, UnsupportedCanonicalization, UnsupportedKeyType, FailedBodyHashMatch, FailedVerification, FailedAuidMatch, RevokedPublicKey, IncompatibleAlgorithms, SignatureExpired, SignatureLength, SignerNotFound, } #[event_type] pub enum SpfEvent { Pass, Fail, SoftFail, Neutral, TempError, PermError, None, } #[event_type] pub enum DmarcEvent { Pass, Fail, PermError, TempError, None, } #[event_type] pub enum IprevEvent { Pass, Fail, PermError, TempError, None, } #[event_type] pub enum MailAuthEvent { ParseError, MissingParameters, NoHeadersFound, Crypto, Io, Base64, DnsError, DnsRecordNotFound, DnsInvalidRecordType, PolicyNotAligned, } #[event_type] pub enum StoreEvent { // Errors AssertValueFailed, FoundationdbError, MysqlError, PostgresqlError, RocksdbError, SqliteError, LdapError, ElasticsearchError, RedisError, S3Error, FilesystemError, PoolError, DataCorruption, DecompressError, DeserializeError, NotFound, NotConfigured, NotSupported, UnexpectedError, CryptoError, // Warnings BlobMissingMarker, // Traces DataWrite, DataIterate, BlobRead, BlobWrite, BlobDelete, SqlQuery, LdapQuery, LdapBind, } #[event_type] pub enum MessageIngestEvent { // Events Ham, Spam, ImapAppend, JmapAppend, Duplicate, Error, } #[event_type] pub enum JmapEvent { // Calls MethodCall, // Method errors InvalidArguments, RequestTooLarge, StateMismatch, AnchorNotFound, UnsupportedFilter, UnsupportedSort, UnknownMethod, InvalidResultReference, Forbidden, AccountNotFound, AccountNotSupportedByMethod, AccountReadOnly, NotFound, CannotCalculateChanges, UnknownDataType, // Request errors UnknownCapability, NotJson, NotRequest, // Not JMAP standard WebsocketStart, WebsocketStop, WebsocketError, } #[event_type] pub enum LimitEvent { SizeRequest, SizeUpload, CallsIn, ConcurrentRequest, ConcurrentUpload, ConcurrentConnection, // Used by listener Quota, BlobQuota, TooManyRequests, } #[event_type] pub enum ManageEvent { MissingParameter, AlreadyExists, AssertFailed, NotFound, NotSupported, Error, } #[event_type] pub enum AuthEvent { Success, Failed, MissingTotp, TooManyAttempts, Error, } #[event_type] pub enum ResourceEvent { NotFound, BadParameters, Error, DownloadExternal, WebadminUnpacked, } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum MetricType { ServerMemory, MessageIngestionTime, MessageFtsIndexTime, MessageSize, MessageAuthSize, DeliveryTotalTime, DeliveryTime, DeliveryActiveConnections, QueueCount, ReportOutgoingSize, StoreReadTime, StoreWriteTime, BlobReadTime, BlobWriteTime, DnsLookupTime, HttpActiveConnections, HttpRequestTime, ImapActiveConnections, ImapRequestTime, Pop3ActiveConnections, Pop3RequestTime, SmtpActiveConnections, SmtpRequestTime, SieveActiveConnections, SieveRequestTime, UserCount, DomainCount, } pub const TOTAL_EVENT_COUNT: usize = total_event_count!(); pub trait AddContext { fn caused_by(self, location: &'static str) -> Result; fn add_context(self, f: F) -> Result where F: FnOnce(Error) -> Error; }