github.com/muhammadn/cortex@v1.9.1-0.20220510110439-46bb7000d03d/pkg/alertmanager/alertmanager_http.go (about)

     1  package alertmanager
     2  
     3  import (
     4  	"net/http"
     5  	"text/template"
     6  
     7  	"github.com/go-kit/log/level"
     8  	"github.com/grafana/dskit/services"
     9  
    10  	util_log "github.com/cortexproject/cortex/pkg/util/log"
    11  )
    12  
    13  var (
    14  	ringStatusPageTemplate = template.Must(template.New("ringStatusPage").Parse(`
    15  	<!DOCTYPE html>
    16  	<html>
    17  		<head>
    18  			<meta charset="UTF-8">
    19  			<title>Cortex Alertmanager Ring</title>
    20  		</head>
    21  		<body>
    22  			<h1>Cortex Alertmanager Ring</h1>
    23  			<p>{{ .Message }}</p>
    24  		</body>
    25  	</html>`))
    26  
    27  	statusTemplate = template.Must(template.New("statusPage").Parse(`
    28      <!doctype html>
    29      <html>
    30          <head><title>Cortex Alertmanager Status</title></head>
    31          <body>
    32              <h1>Cortex Alertmanager Status</h1>
    33              {{ if not .ClusterInfo }}
    34                  <p>Alertmanager gossip-based clustering is disabled.</p>
    35              {{ else }}
    36                  <h2>Node</h2>
    37                  <dl>
    38                      <dt>Name</dt><dd>{{.ClusterInfo.self.Name}}</dd>
    39                      <dt>Addr</dt><dd>{{.ClusterInfo.self.Addr}}</dd>
    40                      <dt>Port</dt><dd>{{.ClusterInfo.self.Port}}</dd>
    41                  </dl>
    42                  <h3>Members</h3>
    43                  {{ with .ClusterInfo.members }}
    44                  <table>
    45                      <tr><th>Name</th><th>Addr</th></tr>
    46                      {{ range . }}
    47                      <tr><td>{{ .Name }}</td><td>{{ .Addr }}</td></tr>
    48                      {{ end }}
    49                  </table>
    50                  {{ else }}
    51                  <p>No peers</p>
    52                  {{ end }}
    53              {{ end }}
    54          </body>
    55      </html>`))
    56  )
    57  
    58  func writeRingStatusMessage(w http.ResponseWriter, message string) {
    59  	w.WriteHeader(http.StatusOK)
    60  	err := ringStatusPageTemplate.Execute(w, struct {
    61  		Message string
    62  	}{Message: message})
    63  	if err != nil {
    64  		level.Error(util_log.Logger).Log("msg", "unable to serve alertmanager ring page", "err", err)
    65  	}
    66  }
    67  
    68  func (am *MultitenantAlertmanager) RingHandler(w http.ResponseWriter, req *http.Request) {
    69  	if !am.cfg.ShardingEnabled {
    70  		writeRingStatusMessage(w, "Alertmanager has no ring because sharding is disabled.")
    71  		return
    72  	}
    73  
    74  	if am.State() != services.Running {
    75  		// we cannot read the ring before the alertmanager is in Running state,
    76  		// because that would lead to race condition.
    77  		writeRingStatusMessage(w, "Alertmanager is not running yet.")
    78  		return
    79  	}
    80  
    81  	am.ring.ServeHTTP(w, req)
    82  }
    83  
    84  // GetStatusHandler returns the status handler for this multi-tenant
    85  // alertmanager.
    86  func (am *MultitenantAlertmanager) GetStatusHandler() StatusHandler {
    87  	return StatusHandler{
    88  		am: am,
    89  	}
    90  }
    91  
    92  // StatusHandler shows the status of the alertmanager.
    93  type StatusHandler struct {
    94  	am *MultitenantAlertmanager
    95  }
    96  
    97  // ServeHTTP serves the status of the alertmanager.
    98  func (s StatusHandler) ServeHTTP(w http.ResponseWriter, _ *http.Request) {
    99  	var clusterInfo map[string]interface{}
   100  	if s.am.peer != nil {
   101  		clusterInfo = s.am.peer.Info()
   102  	}
   103  	err := statusTemplate.Execute(w, struct {
   104  		ClusterInfo map[string]interface{}
   105  	}{
   106  		ClusterInfo: clusterInfo,
   107  	})
   108  	if err != nil {
   109  		level.Error(util_log.Logger).Log("msg", "unable to serve alertmanager status page", "err", err)
   110  		http.Error(w, err.Error(), http.StatusInternalServerError)
   111  	}
   112  }