Source file src/cmd/vendor/github.com/google/pprof/internal/driver/webhtml.go

     1  // Copyright 2017 Google Inc. All Rights Reserved.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package driver
    16  
    17  import (
    18  	"embed"
    19  	"fmt"
    20  	"html/template"
    21  	"os"
    22  	"sync"
    23  
    24  	"github.com/google/pprof/internal/report"
    25  )
    26  
    27  var (
    28  	htmlTemplates    *template.Template // Lazily loaded templates
    29  	htmlTemplateInit sync.Once
    30  )
    31  
    32  // getHTMLTemplates returns the set of HTML templates used by pprof,
    33  // initializing them if necessary.
    34  func getHTMLTemplates() *template.Template {
    35  	htmlTemplateInit.Do(func() {
    36  		htmlTemplates = template.New("templategroup")
    37  		addTemplates(htmlTemplates)
    38  		report.AddSourceTemplates(htmlTemplates)
    39  	})
    40  	return htmlTemplates
    41  }
    42  
    43  //go:embed html
    44  var embeddedFiles embed.FS
    45  
    46  // addTemplates adds a set of template definitions to templates.
    47  func addTemplates(templates *template.Template) {
    48  	// Load specified file.
    49  	loadFile := func(fname string) string {
    50  		data, err := embeddedFiles.ReadFile(fname)
    51  		if err != nil {
    52  			fmt.Fprintf(os.Stderr, "internal/driver: embedded file %q not found\n",
    53  				fname)
    54  			os.Exit(1)
    55  		}
    56  		return string(data)
    57  	}
    58  	loadCSS := func(fname string) string {
    59  		return `<style type="text/css">` + "\n" + loadFile(fname) + `</style>` + "\n"
    60  	}
    61  	loadJS := func(fname string) string {
    62  		return `<script>` + "\n" + loadFile(fname) + `</script>` + "\n"
    63  	}
    64  
    65  	// Define a named template with specified contents.
    66  	def := func(name, contents string) {
    67  		sub := template.New(name)
    68  		template.Must(sub.Parse(contents))
    69  		template.Must(templates.AddParseTree(name, sub.Tree))
    70  	}
    71  
    72  	// Embedded files.
    73  	def("css", loadCSS("html/common.css"))
    74  	def("header", loadFile("html/header.html"))
    75  	def("graph", loadFile("html/graph.html"))
    76  	def("graph_css", loadCSS("html/graph.css"))
    77  	def("script", loadJS("html/common.js"))
    78  	def("top", loadFile("html/top.html"))
    79  	def("sourcelisting", loadFile("html/source.html"))
    80  	def("plaintext", loadFile("html/plaintext.html"))
    81  	// TODO: Rename "stacks" to "flamegraph" to seal moving off d3 flamegraph.
    82  	def("stacks", loadFile("html/stacks.html"))
    83  	def("stacks_css", loadCSS("html/stacks.css"))
    84  	def("stacks_js", loadJS("html/stacks.js"))
    85  }
    86  

View as plain text