func (s *Server) buildNamespaceSet() {
	namespaces := make(map[string]struct{})
	ns := strings.Split(s.conf.Namespace, ",")
	for _, n := range ns {
		namespace := strings.TrimSpace(n)
		if namespace != "" {
			namespaces[namespace] = struct{}{}
		}
	}
	s.namespaces = namespaces
}
buildNamespaceSet takes the namespaces passed in config and creates
a Set to efficiently check whether a given namespace is supported.
package main
import (
	"context"
	"encoding/json"
	"fmt"
	"html/template"
	"log"
	"net/http"
	"net/url"
	"regexp"
	"strings"
	"time"
	"cloud.google.com/go/logging"
	"cloud.google.com/go/logging/logadmin"
	"github.com/tektoncd/plumbing/pipelinerun-logs/pkg/config"
	"golang.org/x/xerrors"
	"google.golang.org/api/iterator"
)
type Server struct {
	conf        *config.Config
	client      *logging.Client
	adminClient *logadmin.Client
	entriesTmpl *template.Template
	namespaces  map[string]struct{}
}
type EntriesTemplateContext struct {
	LogsJSON     []RenderableEntry
	BuildID      string
	PipelineName string
}
type logRequestParams struct {
	namespace string
	buildID   string
}
const (
	EntryParseErrorMessage           = "unable to parse entry"
	MaxFetchedLogEntries             = 100000
	StackdriverContainerNameLabel    = "container_name"
	StackdriverContainerResourceType = "k8s_container"
	TektonPipelineNameLabel          = "k8s-pod/tekton_dev/pipeline"
	TektonTaskNameLabel              = "k8s-pod/tekton_dev/task"
)
var (
	prowBuildIDPattern = regexp.MustCompile(`[0-9]+`)
	uuidBuildIDPattern = regexp.MustCompile(`[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}`)
)
func NewServer(conf *config.Config, client *logging.Client, adminClient *logadmin.Client, templatePath string) *Server {
	s := &Server{
		conf:        conf,
		client:      client,
		adminClient: adminClient,
		entriesTmpl: template.Must(template.ParseFiles(templatePath)),
	}
	s.buildNamespaceSet()
	return s
}