github.com/grafana/pyroscope@v1.18.0/pkg/operations/v2/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 (v2) - {{ .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 (v2): 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="form-check"> 39 <input class="form-check-input" type="radio" name="view" id="view-table" value="table" {{ if eq .Query.View "table" }} checked {{ end }}> 40 <label class="form-check-label" for="view"> 41 Table 42 </label> 43 </div> 44 <div class="form-check"> 45 <input class="form-check-input" type="radio" name="view" id="view-grid" value="grid" {{ if eq .Query.View "grid" }} checked {{ end }}> 46 <label class="form-check-label" for="view-grid"> 47 Grid 48 </label> 49 </div> 50 <hr/> 51 <div class="input-group"> 52 <input type="text" class="form-control" placeholder="From" name="queryFrom" 53 value="{{ .Query.From }}"> 54 <input type="text" class="form-control" placeholder="To" name="queryTo" value="{{ .Query.To }}"> 55 <button type="submit" class="btn btn-secondary">Reload</button> 56 </div> 57 </form> 58 </div> 59 </div> 60 <div class="row my-3"> 61 <h5>{{ len $.SelectedBlocks.BlockGroups }} block groups found</h5> 62 {{ $user := .User }} 63 {{ if eq .Query.View "table"}} 64 <div class="accordion"> 65 {{ range $i, $blockGroup := .SelectedBlocks.BlockGroups }} 66 <div class="accordion-item"> 67 <h2 class="accordion-header"> 68 <button class="accordion-button collapsed acc-btn" type="button" data-bs-toggle="collapse" 69 data-bs-target="#group-{{ $i }}" aria-expanded="true" aria-controls="collapseOne"> 70 <span class="title"> 71 {{ $blockGroup.FormattedMinTime }}: {{ len $blockGroup.Blocks }} blocks 72 </span> 73 <span class="time"> 74 {{ $blockGroup.MinTimeAge }} 75 </span> 76 </button> 77 </h2> 78 <div class="accordion-collapse collapse" id="group-{{ $i }}"> 79 <div class="accordion-body"> 80 <div class="table-responsive"> 81 <table class="table table-bordered table-hover table-striped"> 82 <thead> 83 <tr> 84 <th>ID</th> 85 <th>Min Time</th> 86 <th>Max Time</th> 87 <th>Duration</th> 88 <th>Compaction Level</th> 89 <th>Shard</th> 90 <th>Size</th> 91 </tr> 92 </thead> 93 <tbody> 94 {{ range $, $v := $blockGroup.Blocks }} 95 <tr> 96 <td class="font-monospace small"> 97 <a href="blocks/{{ $v.ID }}?shard={{ $v.Shard }}&block_tenant={{ $v.BlockTenant }}"> 98 {{ $v.ID }} 99 </a> 100 </td> 101 <td class="font-monospace small">{{ $v.MinTime }}</td> 102 <td class="font-monospace small">{{ $v.MaxTime }}</td> 103 <td class="font-monospace small">{{ $v.FormattedDuration }}</td> 104 <td class="font-monospace small">{{ $v.CompactionLevel }}</td> 105 <td class="font-monospace small">{{ $v.Shard }}</td> 106 <td class="font-monospace small">{{ $v.Size }}</td> 107 </tr> 108 {{ end }} 109 </tbody> 110 </table> 111 </div> 112 </div> 113 </div> 114 </div> 115 {{ end }} 116 </div> 117 {{ else }} 118 <hr/> 119 {{ $groupDuration := .SelectedBlocks.GroupDurationMinutes}} 120 {{ $blockWidth := 20 }} 121 {{ $blockSpacing := 2 }} 122 {{ if gt .SelectedBlocks.MaxBlocksPerGroup 32 }} 123 {{ $blockWidth = 10 }} 124 {{ $blockSpacing = 1 }} 125 {{ end }} 126 <div> 127 <div style="position: relative"> 128 {{ range $i, $blockGroup := .SelectedBlocks.BlockGroups }} 129 {{ range $j, $block := $blockGroup.Blocks }} 130 {{ if lt $j 80 }} 131 {{ $height := mulf 5 (divf $block.Duration $groupDuration) }} 132 {{ $heightEm := format "%.1f" $height }} 133 {{ $top := addf (mulf (float $i) 5.0) (subf 5.0 $height) }} 134 {{ $topEm := format "%.1f" $top }} 135 {{ $color := "#d3d3d3" }} 136 {{ if eq 2 $block.CompactionLevel }} 137 {{ $color = "#ffa500"}} 138 {{ else if eq 3 $block.CompactionLevel }} 139 {{ $color = "#9acd32"}} 140 {{ else if gt $block.CompactionLevel 3 }} 141 {{ $color = "#008000"}} 142 {{ end }} 143 <a href="blocks/{{ $block.ID }}?shard={{ $block.Shard }}&block_tenant={{ $block.BlockTenant }}"> 144 <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> 145 </a> 146 {{ end}} 147 {{ end }} 148 {{ end }} 149 </div> 150 </div> 151 {{ range $i, $blockGroup := .SelectedBlocks.BlockGroups }} 152 <div style="position: relative; left: 0; top: {{ add (mul (add 1 $i) 5) -1 }}em; height: 0"> 153 <small>{{ $blockGroup.FormattedMinTime }}: {{ len $blockGroup.Blocks }} blocks</small> 154 </div> 155 {{ end }} 156 {{ end }} 157 </div> 158 </div> 159 </main> 160 </body> 161 </html>