2013-07-16 15:03:56 +00:00
// Copyright 2013 Prometheus Team
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package main
import (
2013-07-22 09:05:49 +00:00
"flag"
2015-06-25 15:59:00 +00:00
"fmt"
"net"
2013-08-14 12:02:57 +00:00
"os"
2015-04-29 19:39:59 +00:00
"strings"
2013-07-31 15:49:29 +00:00
"time"
2013-07-17 15:45:01 +00:00
2015-05-23 20:34:45 +00:00
"github.com/prometheus/log"
2013-08-27 13:32:08 +00:00
2013-08-05 09:49:56 +00:00
"github.com/prometheus/alertmanager/config"
"github.com/prometheus/alertmanager/manager"
"github.com/prometheus/alertmanager/web"
"github.com/prometheus/alertmanager/web/api"
2013-07-16 15:03:56 +00:00
)
2013-07-26 01:04:53 +00:00
var (
2015-02-08 22:20:09 +00:00
configFile = flag . String ( "config.file" , "alertmanager.conf" , "Alert Manager configuration file name." )
silencesFile = flag . String ( "silences.file" , "silences.json" , "Silence storage file name." )
minRefreshPeriod = flag . Duration ( "alerts.min-refresh-period" , 5 * time . Minute , "Minimum required alert refresh period before an alert is purged." )
2015-06-25 15:59:00 +00:00
listenAddress = flag . String ( "web.listen-address" , ":9093" , "Address to listen on for the web interface and API." )
2015-04-29 19:39:59 +00:00
pathPrefix = flag . String ( "web.path-prefix" , "/" , "Prefix for all web paths." )
2015-06-25 15:59:00 +00:00
hostname = flag . String ( "web.hostname" , "" , "Hostname on which the Alertmanager is available to the outside world." )
2015-07-24 05:34:10 +00:00
externalURL = flag . String ( "web.external-url" , "" , "The URL under which Alertmanager is externally reachable (for example, if Alertmanager is served via a reverse proxy). Used for generating relative and absolute links back to Alertmanager itself. If omitted, relevant URL components will be derived automatically." )
2013-07-26 01:04:53 +00:00
)
2015-07-24 05:34:10 +00:00
func alertmanagerURL ( hostname , pathPrefix , addr , externalURL string ) ( string , error ) {
if externalURL != "" {
return externalURL , nil
}
2015-06-25 15:59:00 +00:00
var err error
if hostname == "" {
hostname , err = os . Hostname ( )
if err != nil {
return "" , err
}
}
_ , port , err := net . SplitHostPort ( addr )
if err != nil {
return "" , err
}
return fmt . Sprintf ( "http://%s:%s%s" , hostname , port , pathPrefix ) , nil
}
2013-07-16 15:03:56 +00:00
func main ( ) {
2013-07-22 09:05:49 +00:00
flag . Parse ( )
2015-04-29 19:39:59 +00:00
if ! strings . HasPrefix ( * pathPrefix , "/" ) {
* pathPrefix = "/" + * pathPrefix
}
if ! strings . HasSuffix ( * pathPrefix , "/" ) {
* pathPrefix = * pathPrefix + "/"
}
2013-08-14 12:02:57 +00:00
versionInfoTmpl . Execute ( os . Stdout , BuildInfo )
2013-08-02 15:22:26 +00:00
conf := config . MustLoadFromFile ( * configFile )
2013-07-26 01:04:53 +00:00
2013-07-31 12:39:01 +00:00
silencer := manager . NewSilencer ( )
defer silencer . Close ( )
2013-07-16 15:03:56 +00:00
2013-08-02 15:22:26 +00:00
err := silencer . LoadFromFile ( * silencesFile )
2013-07-31 15:49:29 +00:00
if err != nil {
2015-05-23 20:34:45 +00:00
log . Warn ( "Couldn't load silences, starting up with empty silence list: " , err )
2013-07-31 15:49:29 +00:00
}
saveSilencesTicker := time . NewTicker ( 10 * time . Second )
go func ( ) {
2015-05-20 22:01:17 +00:00
for range saveSilencesTicker . C {
2013-07-31 15:49:29 +00:00
if err := silencer . SaveToFile ( * silencesFile ) ; err != nil {
2015-05-23 20:34:45 +00:00
log . Error ( "Error saving silences to file: " , err )
2013-07-31 15:49:29 +00:00
}
}
} ( )
defer saveSilencesTicker . Stop ( )
2015-07-24 05:34:10 +00:00
amURL , err := alertmanagerURL ( * hostname , * pathPrefix , * listenAddress , * externalURL )
2015-06-25 15:59:00 +00:00
if err != nil {
log . Fatalln ( "Error building Alertmanager URL:" , err )
}
notifier := manager . NewNotifier ( conf . NotificationConfig , amURL )
2013-07-30 11:19:18 +00:00
defer notifier . Close ( )
2013-07-26 00:05:52 +00:00
2013-08-27 13:32:08 +00:00
inhibitor := new ( manager . Inhibitor )
inhibitor . SetInhibitRules ( conf . InhibitRules ( ) )
options := & manager . MemoryAlertManagerOptions {
Inhibitor : inhibitor ,
Silencer : silencer ,
Notifier : notifier ,
MinRefreshInterval : * minRefreshPeriod ,
}
alertManager := manager . NewMemoryAlertManager ( options )
alertManager . SetAggregationRules ( conf . AggregationRules ( ) )
go alertManager . Run ( )
2013-07-16 15:03:56 +00:00
2013-08-27 13:32:08 +00:00
// Web initialization.
2013-08-14 12:02:57 +00:00
flags := map [ string ] string { }
flag . VisitAll ( func ( f * flag . Flag ) {
flags [ f . Name ] = f . Value . String ( )
} )
statusHandler := & web . StatusHandler {
2015-04-29 19:39:59 +00:00
Config : conf . String ( ) ,
Flags : flags ,
BuildInfo : BuildInfo ,
Birth : time . Now ( ) ,
PathPrefix : * pathPrefix ,
2013-08-14 12:02:57 +00:00
}
2013-07-17 15:45:01 +00:00
webService := & web . WebService {
2013-07-23 08:40:23 +00:00
// REST API Service.
2013-07-17 15:45:01 +00:00
AlertManagerService : & api . AlertManagerService {
2015-04-29 19:39:59 +00:00
Manager : alertManager ,
Silencer : silencer ,
PathPrefix : * pathPrefix ,
2013-07-17 15:45:01 +00:00
} ,
2013-07-23 08:40:23 +00:00
// Template-based page handlers.
2013-07-18 12:49:37 +00:00
AlertsHandler : & web . AlertsHandler {
2013-08-27 13:32:08 +00:00
Manager : alertManager ,
IsSilencedInterrogator : silencer ,
2015-10-08 12:48:38 +00:00
PathPrefix : * pathPrefix ,
2013-07-18 12:49:37 +00:00
} ,
2013-07-23 08:40:23 +00:00
SilencesHandler : & web . SilencesHandler {
2015-10-08 12:48:38 +00:00
Silencer : silencer ,
PathPrefix : * pathPrefix ,
2013-07-23 08:40:23 +00:00
} ,
2013-08-14 12:02:57 +00:00
StatusHandler : statusHandler ,
2013-07-17 15:45:01 +00:00
}
2015-06-25 15:59:00 +00:00
go webService . ServeForever ( * listenAddress , * pathPrefix )
2013-07-16 15:03:56 +00:00
2013-08-27 13:32:08 +00:00
// React to configuration changes.
2013-08-02 15:22:26 +00:00
watcher := config . NewFileWatcher ( * configFile )
go watcher . Watch ( func ( conf * config . Config ) {
2013-08-27 13:32:08 +00:00
inhibitor . SetInhibitRules ( conf . InhibitRules ( ) )
2013-08-02 15:22:26 +00:00
notifier . SetNotificationConfigs ( conf . NotificationConfig )
2013-08-27 13:32:08 +00:00
alertManager . SetAggregationRules ( conf . AggregationRules ( ) )
2013-08-14 12:02:57 +00:00
statusHandler . UpdateConfig ( conf . String ( ) )
2013-08-02 15:22:26 +00:00
} )
2015-05-23 20:34:45 +00:00
log . Info ( "Running notification dispatcher..." )
2013-08-27 13:32:08 +00:00
notifier . Dispatch ( )
2013-07-16 15:03:56 +00:00
}