golang.org/x/build@v0.0.0-20240506185731-218518f32b70/perf/app/app.go (about)

     1  // Copyright 2017 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // Package app implements the performance data analysis server.
     6  package app
     7  
     8  import (
     9  	"embed"
    10  	"net/http"
    11  
    12  	"github.com/google/safehtml/template"
    13  	"golang.org/x/build/perfdata"
    14  )
    15  
    16  var (
    17  	//go:embed template/*
    18  	tmplEmbedFS embed.FS
    19  	tmplFS      = template.TrustedFSFromEmbed(tmplEmbedFS)
    20  )
    21  
    22  // App manages the analysis server logic.
    23  // Construct an App instance and call RegisterOnMux to connect it with an HTTP server.
    24  type App struct {
    25  	// StorageClient is used to talk to the perfdata server.
    26  	StorageClient *perfdata.Client
    27  
    28  	// BaseDir is the directory containing the "template" directory.
    29  	// If empty, the current directory will be used.
    30  	BaseDir string
    31  
    32  	// InfluxHost is the host URL of the perf InfluxDB server.
    33  	InfluxHost string
    34  
    35  	// InfluxToken is the Influx auth token for connecting to InfluxHost.
    36  	//
    37  	// If empty, we attempt to fetch the token from Secret Manager using
    38  	// InfluxProject.
    39  	InfluxToken string
    40  
    41  	// InfluxProject is the GCP project ID containing the InfluxDB secrets.
    42  	//
    43  	// If empty, this defaults to the project this service is running as.
    44  	//
    45  	// Only used if InfluxToken is empty.
    46  	InfluxProject string
    47  
    48  	// AuthCronEmail is the service account email which requests to
    49  	// /cron/syncinflux must contain an OICD authentication token for, with
    50  	// audience "/cron/syncinflux".
    51  	//
    52  	// If empty, no authentication is required.
    53  	AuthCronEmail string
    54  }
    55  
    56  // RegisterOnMux registers the app's URLs on mux.
    57  func (a *App) RegisterOnMux(mux *http.ServeMux) {
    58  	mux.HandleFunc("/", a.index)
    59  	mux.HandleFunc("/search", a.search)
    60  	mux.HandleFunc("/compare", a.compare)
    61  	mux.HandleFunc("/cron/syncinflux", a.syncInflux)
    62  	a.dashboardRegisterOnMux(mux)
    63  }
    64  
    65  // search handles /search.
    66  // This currently just runs the compare handler, until more analysis methods are implemented.
    67  func (a *App) search(w http.ResponseWriter, r *http.Request) {
    68  	if err := r.ParseForm(); err != nil {
    69  		http.Error(w, err.Error(), 500)
    70  		return
    71  	}
    72  	if r.Header.Get("Accept") == "text/plain" || r.Header.Get("X-Benchsave") == "1" {
    73  		// TODO(quentin): Switch to real Accept negotiation when golang/go#19307 is resolved.
    74  		// Benchsave sends both of these headers.
    75  		a.textCompare(w, r)
    76  		return
    77  	}
    78  	// TODO(quentin): Intelligently choose an analysis method
    79  	// based on the results from the query, once there is more
    80  	// than one analysis method.
    81  	//q := r.Form.Get("q")
    82  	a.compare(w, r)
    83  }