github.com/grafana/pyroscope@v1.18.0/pkg/operations/v2/pages.go (about) 1 package v2 2 3 import ( 4 _ "embed" 5 "fmt" 6 "html/template" 7 ) 8 9 //go:embed tool.blocks.index.gohtml 10 var indexPageHtml string 11 12 //go:embed tool.blocks.list.gohtml 13 var blocksPageHtml string 14 15 //go:embed tool.blocks.detail.gohtml 16 var blockDetailsPageHtml string 17 18 //go:embed tool.blocks.dataset.gohtml 19 var datasetDetailsPageHtml string 20 21 //go:embed tool.blocks.dataset.profiles.gohtml 22 var datasetProfilesPageHtml string 23 24 //go:embed tool.blocks.profile.call.tree.gohtml 25 var profileCallTreePageHtml string 26 27 //go:embed tool.pagination.gohtml 28 var paginationHtml string 29 30 //go:embed tool.blocks.dataset.index.gohtml 31 var datasetIndexPageHtml string 32 33 //go:embed tool.blocks.dataset.symbols.gohtml 34 var datasetSymbolsPageHtml string 35 36 type indexPageContent struct { 37 Users []string 38 Now string 39 } 40 41 type blockListPageContent struct { 42 User string 43 SelectedBlocks *blockListResult 44 Query *blockQuery 45 Now string 46 } 47 48 type blockDetailsPageContent struct { 49 User string 50 Block *blockDetails 51 Shard uint32 52 BlockTenant string 53 Now string 54 } 55 56 type datasetDetailsPageContent struct { 57 User string 58 BlockID string 59 Shard uint32 60 BlockTenant string 61 Dataset *datasetDetails 62 Now string 63 } 64 65 type datasetProfilesPageContent struct { 66 User string 67 BlockID string 68 Shard uint32 69 BlockTenant string 70 Dataset *datasetDetails 71 Profiles []profileInfo 72 TotalCount int 73 Page int 74 PageSize int 75 TotalPages int 76 HasPrevPage bool 77 HasNextPage bool 78 Now string 79 } 80 81 type templates struct { 82 indexTemplate *template.Template 83 blocksTemplate *template.Template 84 blockDetailsTemplate *template.Template 85 datasetDetailsTemplate *template.Template 86 datasetProfilesTemplate *template.Template 87 profileCallTreeTemplate *template.Template 88 datasetIndexTemplate *template.Template 89 datasetSymbolsTemplate *template.Template 90 } 91 92 var pageTemplates = initTemplates() 93 94 func initTemplates() *templates { 95 indexTemplate := template.New("index") 96 template.Must(indexTemplate.Parse(indexPageHtml)) 97 blocksTemplate := template.New("blocks").Funcs(template.FuncMap{ 98 "mul": mul, 99 "add": add, 100 "addf": addf, 101 "subf": subf, 102 "mulf": mulf, 103 "divf": divf, 104 "format": format, 105 "float": float, 106 }) 107 template.Must(blocksTemplate.Parse(blocksPageHtml)) 108 blockDetailsTemplate := template.New("block-details") 109 template.Must(blockDetailsTemplate.Parse(blockDetailsPageHtml)) 110 datasetDetailsTemplate := template.New("dataset-details") 111 template.Must(datasetDetailsTemplate.Parse(datasetDetailsPageHtml)) 112 datasetProfilesTemplate := template.New("dataset-profiles").Funcs(template.FuncMap{ 113 "add": add, 114 "mul": mul, 115 "seq": seq, 116 "dict": dict, 117 }) 118 template.Must(datasetProfilesTemplate.Parse(paginationHtml)) 119 template.Must(datasetProfilesTemplate.Parse(datasetProfilesPageHtml)) 120 profileCallTreeTemplate := template.New("profile-call-tree").Funcs(template.FuncMap{ 121 "add": add, 122 "dict": dict, 123 }) 124 template.Must(profileCallTreeTemplate.Parse(profileCallTreePageHtml)) 125 datasetIndexTemplate := template.New("dataset-index") 126 template.Must(datasetIndexTemplate.Parse(datasetIndexPageHtml)) 127 datasetSymbolsTemplate := template.New("dataset-symbols").Funcs(template.FuncMap{ 128 "add": add, 129 "mul": mul, 130 "seq": seq, 131 "dict": dict, 132 }) 133 template.Must(datasetSymbolsTemplate.Parse(paginationHtml)) 134 template.Must(datasetSymbolsTemplate.Parse(datasetSymbolsPageHtml)) 135 t := &templates{ 136 indexTemplate: indexTemplate, 137 blocksTemplate: blocksTemplate, 138 blockDetailsTemplate: blockDetailsTemplate, 139 datasetDetailsTemplate: datasetDetailsTemplate, 140 datasetProfilesTemplate: datasetProfilesTemplate, 141 profileCallTreeTemplate: profileCallTreeTemplate, 142 datasetIndexTemplate: datasetIndexTemplate, 143 datasetSymbolsTemplate: datasetSymbolsTemplate, 144 } 145 return t 146 } 147 148 func mul(param1, param2 int) int { 149 return param1 * param2 150 } 151 152 func mulf(param1, param2 float64) float64 { 153 return param1 * param2 154 } 155 156 func add(param1, param2 int) int { 157 return param1 + param2 158 } 159 160 func addf(param1, param2 float64) float64 { 161 return param1 + param2 162 } 163 164 func subf(param1, param2 float64) float64 { 165 return param1 - param2 166 } 167 168 func divf(param1, param2 int) float64 { 169 return float64(param1) / float64(param2) 170 } 171 172 func format(format string, value any) string { 173 return fmt.Sprintf(format, value) 174 } 175 176 func float(param int) float64 { 177 return float64(param) 178 } 179 180 // dict creates a map for passing multiple values to a template 181 func dict(values ...interface{}) (map[string]interface{}, error) { 182 if len(values)%2 != 0 { 183 return nil, fmt.Errorf("dict requires an even number of arguments") 184 } 185 dict := make(map[string]interface{}, len(values)/2) 186 for i := 0; i < len(values); i += 2 { 187 key, ok := values[i].(string) 188 if !ok { 189 return nil, fmt.Errorf("dict keys must be strings") 190 } 191 dict[key] = values[i+1] 192 } 193 return dict, nil 194 } 195 196 // seq generates a sequence of integers from start to end (inclusive) 197 func seq(start, end int) []int { 198 if start > end { 199 return []int{} 200 } 201 result := make([]int, end-start+1) 202 for i := range result { 203 result[i] = start + i 204 } 205 return result 206 }