github.com/grafana/pyroscope@v1.18.0/pkg/operations/tool.blocks.list.gohtml (about) 1 <!DOCTYPE html> 2 <html class="h-100" data-bs-theme="dark"> 3 <head> 4 <meta charset="UTF-8"> 5 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 6 <meta name="viewport" content="width=device-width, initial-scale=1"> 7 8 <title>Bucket Blocks Tool - {{ .User }}</title> 9 10 <link rel="stylesheet" href="/static/bootstrap-5.3.3.min.css"> 11 <link rel="stylesheet" href="/static/bootstrap-icons-1.8.1.css"> 12 <link rel="stylesheet" href="/static/pyroscope-styles.css"> 13 <script src="/static/bootstrap-5.3.3.bundle.min.js"></script> 14 <style> 15 button.acc-btn { 16 display: grid; 17 grid-template-columns: 1fr max-content max-content; 18 grid-gap: 10px; 19 } 20 </style> 21 </head> 22 <body class="d-flex flex-column h-100"> 23 <main class="flex-shrink-0"> 24 <div class="container"> 25 <div class="header row border-bottom py-3 flex-column-reverse flex-sm-row"> 26 <div class="col-12 col-sm-9 text-center text-sm-start"> 27 <h3>Bucket Blocks Explorer: Tenant {{ .User }}</h3> 28 </div> 29 <div class="col-12 col-sm-3 text-center text-sm-end mb-3 mb-sm-0"> 30 <a href="../../tenants"> 31 <img alt="Pyroscope logo" class="pyroscope-brand" src="/static/pyroscope-logo.png"> 32 </a> 33 </div> 34 </div> 35 <div class="row my-3"> 36 <div class="col-md-6"> 37 <form class="card p-2" action="blocks" method="get"> 38 <div class="input-group"> 39 <div class="form-check"> 40 <input type="checkbox" class="form-check-input" id="include-deleted" name="includeDeleted" value="true" {{ if .Query.IncludeDeleted }} checked {{ end }}> 41 <label class="form-check-label" for="include-deleted">Include deleted blocks</label> 42 </div> 43 </div> 44 <hr/> 45 <div class="form-check"> 46 <input class="form-check-input" type="radio" name="view" id="view-table" value="table" {{ if eq .Query.View "table" }} checked {{ end }}> 47 <label class="form-check-label" for="view"> 48 Table 49 </label> 50 </div> 51 <div class="form-check"> 52 <input class="form-check-input" type="radio" name="view" id="view-grid" value="grid" {{ if eq .Query.View "grid" }} checked {{ end }}> 53 <label class="form-check-label" for="view-grid"> 54 Grid 55 </label> 56 </div> 57 <hr/> 58 <div class="input-group"> 59 <input type="text" class="form-control" placeholder="From" name="queryFrom" 60 value="{{ .Query.From }}"> 61 <input type="text" class="form-control" placeholder="To" name="queryTo" value="{{ .Query.To }}"> 62 <button type="submit" class="btn btn-secondary">Reload</button> 63 </div> 64 </form> 65 </div> 66 </div> 67 <div class="row my-3"> 68 <h5>{{ len $.SelectedBlocks.BlockGroups }} block groups found</h5> 69 {{ $user := .User }} 70 {{ if eq .Query.View "table"}} 71 <div class="accordion"> 72 {{ range $i, $blockGroup := .SelectedBlocks.BlockGroups }} 73 <div class="accordion-item"> 74 <h2 class="accordion-header"> 75 <button class="accordion-button collapsed acc-btn" type="button" data-bs-toggle="collapse" 76 data-bs-target="#group-{{ $i }}" aria-expanded="true" aria-controls="collapseOne"> 77 <span class="title"> 78 {{ $blockGroup.FormattedMinTime }}: {{ len $blockGroup.Blocks }} blocks 79 </span> 80 <span class="time"> 81 {{ $blockGroup.MinTimeAge }} 82 </span> 83 </button> 84 </h2> 85 <div class="accordion-collapse collapse" id="group-{{ $i }}"> 86 <div class="accordion-body"> 87 <div class="table-responsive"> 88 <table class="table table-bordered table-hover table-striped"> 89 <thead> 90 <tr> 91 <th>ID</th> 92 <th>Upload Time</th> 93 <th>Min Time</th> 94 <th>Max Time</th> 95 <th>Duration</th> 96 <th>Compaction Level</th> 97 <th>Compactor Shard ID</th> 98 </tr> 99 </thead> 100 <tbody> 101 {{ range $, $v := $blockGroup.Blocks }} 102 <tr> 103 <td class="font-monospace small"> 104 <a href="blocks/{{ $v.ID }}"> 105 {{ $v.ID }} 106 </a> 107 </td> 108 <td class="font-monospace small">{{ $v.UploadedAt }}</td> 109 <td class="font-monospace small">{{ $v.MinTime }}</td> 110 <td class="font-monospace small">{{ $v.MaxTime }}</td> 111 <td class="font-monospace small">{{ $v.FormattedDuration }}</td> 112 <td class="font-monospace small">{{ $v.CompactionLevel }}</td> 113 <td class="font-monospace small">{{ $v.CompactorShardID }}</td> 114 </tr> 115 {{ end }} 116 </tbody> 117 </table> 118 </div> 119 </div> 120 </div> 121 </div> 122 {{ end }} 123 </div> 124 {{ else }} 125 <hr/> 126 {{ $groupDuration := .SelectedBlocks.GroupDurationMinutes}} 127 {{ $blockWidth := 20 }} 128 {{ $blockSpacing := 2 }} 129 {{ if gt .SelectedBlocks.MaxBlocksPerGroup 32 }} 130 {{ $blockWidth = 10 }} 131 {{ $blockSpacing = 1 }} 132 {{ end }} 133 <div> 134 <div style="position: relative"> 135 {{ range $i, $blockGroup := .SelectedBlocks.BlockGroups }} 136 {{ range $j, $block := $blockGroup.Blocks }} 137 {{ if lt $j 80 }} 138 {{ $height := mulf 5 (divf $block.Duration $groupDuration) }} 139 {{ $heightEm := format "%.1f" $height }} 140 {{ $top := addf (mulf (float $i) 5.0) (subf 5.0 $height) }} 141 {{ $topEm := format "%.1f" $top }} 142 {{ $color := "#d3d3d3" }} 143 {{ if eq 2 $block.CompactionLevel }} 144 {{ $color = "#ffa500"}} 145 {{ else if eq 3 $block.CompactionLevel }} 146 {{ $color = "#9acd32"}} 147 {{ else if gt $block.CompactionLevel 3 }} 148 {{ $color = "#008000"}} 149 {{ end }} 150 <a href="blocks/{{ $block.ID }}"> 151 <button style="position: absolute; background-color: {{ $color }}; top: {{ $topEm }}em; padding: 0; left: {{ add 20 (mul $j $blockSpacing)}}%; width: {{ $blockWidth }}px; height: {{ $heightEm }}em;"></button> 152 </a> 153 {{ end}} 154 {{ end }} 155 {{ end }} 156 </div> 157 </div> 158 {{ range $i, $blockGroup := .SelectedBlocks.BlockGroups }} 159 <div style="position: relative; left: 0; top: {{ add (mul (add 1 $i) 5) -1 }}em; height: 0"> 160 <small>{{ $blockGroup.FormattedMinTime }}: {{ len $blockGroup.Blocks }} blocks</small> 161 </div> 162 {{ end }} 163 {{ end }} 164 </div> 165 </div> 166 </main> 167 </body> 168 </html>