func Run(ctx context.Context, st storage.RootsReader, rep incident.Reporter, l *ctlog.Log) {
	rootSetChan, err := st.WatchRoots(ctx, l)
	if err != nil {
		glog.Errorf("%s: %s: storage.RootsReader.WatchRoots() = %q", l.URL, logStr, err)
		return
	}
	var lastRootSetID storage.RootSetID
	for {
		select {
		case <-ctx.Done():
			return
		case rootSetID := <-rootSetChan:
			if lastRootSetID != "" && lastRootSetID != rootSetID {
				oldRoots, err := st.ReadRoots(ctx, lastRootSetID)
				if err != nil {
					glog.Errorf("%s: %s: %s", l.URL, logStr, err)
					return
				}
				newRoots, err := st.ReadRoots(ctx, rootSetID)
				if err != nil {
					glog.Errorf("%s: %s: %s", l.URL, logStr, err)
					return
				}
				addedCerts, removedCerts := diffRootSets(oldRoots, newRoots)
				if err := reportChange(ctx, rep, l, addedCerts, removedCerts); err != nil {
					glog.Errorf("%s: %s: %s", l.URL, logStr, err)
					return
				}
			}
			lastRootSetID = rootSetID
		}
	}
}
Run starts a Roots Analyzer, which watches a CT log's root certificates and creates incident reports for changes to them.
package rootsanalyzer
import (
	"bytes"
	"context"
	"crypto/sha256"
	"net/url"
	"path"
	"sort"
	"strings"
	"text/template"
	"github.com/golang/glog"
	ct "github.com/google/certificate-transparency-go"
	"github.com/google/certificate-transparency-go/x509"
	"github.com/google/monologue/ctlog"
	"github.com/google/monologue/incident"
	"github.com/google/monologue/storage"
)
const logStr = "Roots Analyzer"
var (
	incidentTemplate = template.Must(template.New("roots_incident").Funcs(template.FuncMap{
		"sha256": sha256.Sum256,
	}).Parse(`The root certificates accepted by {{ .Log.Name }} ({{ .Log.URL }}) have changed.
{{ if gt (len .AddedCerts) 0 }}
Certificates added ({{ len .AddedCerts }}):
{{ range .AddedCerts }}{{ .Subject }} (SHA256: {{ sha256 .Raw | printf "%X" }})
{{ end }}{{ end }}{{ if gt (len .RemovedCerts) 0 }}
Certificates removed ({{ len .RemovedCerts }}):
{{ range .RemovedCerts }}{{ .Subject }} (SHA256: {{ sha256 .Raw | printf "%X" }})
{{ end }}{{ end }}`))
)
type incidentTemplateArgs struct {
	Log          *ctlog.Log
	AddedCerts   []*x509.Certificate
	RemovedCerts []*x509.Certificate
}