github.com/openshift-online/ocm-sdk-go@v0.1.473/metrics/path_tree.go (about) 1 /* 2 Copyright (c) 2021 Red Hat, Inc. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 // This file contains the type that describes trees of URL paths used to translate request paths 18 // into labes suitalbe for use as Prometheus labels. 19 20 package metrics 21 22 import ( 23 "strings" 24 25 jsoniter "github.com/json-iterator/go" 26 ) 27 28 // pathTree defines a tree of URL paths that will be used to transform request paths into labels 29 // suitable for use in Prometheus metrics. For example, a server that has these URL paths: 30 // 31 // /api 32 // /api/clusters_mgmt 33 // /api/clusters_mgmt/v1 34 // /api/clusters_mgmt/v1/clusters 35 // /api/clusters_mgmt/v1/clusters/{cluster_id} 36 // /api/clusters_mgmt/v1/clusters/{cluster_id}/groups 37 // /api/clusters_mgmt/v1/clusters/{cluster_id}/groups/{group_id} 38 // 39 // Will be described with a tree like this: 40 // 41 // var pathRoot = pathTree{ 42 // "api": { 43 // "clusters_mgmt": { 44 // "v1": { 45 // "clusters": { 46 // "-": { 47 // "groups": { 48 // "-": nil, 49 // }, 50 // }, 51 // }, 52 // }, 53 // }, 54 // }, 55 // } 56 // 57 // Path variables are represented with a dash. 58 type pathTree map[string]pathTree 59 60 // copy creates a deep copy of this tree. 61 func (t pathTree) copy() pathTree { 62 if t == nil { 63 return nil 64 } 65 tree := pathTree{} 66 for label, child := range t { 67 tree[label] = child.copy() 68 } 69 return tree 70 } 71 72 // add adds the given branch to this tree. 73 func (t pathTree) add(path string) { 74 path = t.clean(path) 75 if len(path) == 0 { 76 return 77 } 78 segments := strings.Split(path, "/") 79 t.addSegments(segments) 80 } 81 82 func (t pathTree) addSegments(segments []string) { 83 if len(segments) == 0 { 84 return 85 } 86 head := segments[0] 87 tail := segments[1:] 88 next := t[head] 89 if next == nil { 90 if len(tail) > 0 { 91 next = pathTree{} 92 } 93 t[head] = next 94 } 95 next.addSegments(tail) 96 } 97 98 func (t pathTree) clean(path string) string { 99 for len(path) > 0 && strings.HasPrefix(path, "/") { 100 path = path[1:] 101 } 102 for len(path) > 0 && strings.HasSuffix(path, "/") { 103 path = path[0 : len(path)-1] 104 } 105 return path 106 } 107 108 // pathRoot is the root of the URL path tree. 109 var pathRoot pathTree 110 111 func init() { 112 err := jsoniter.Unmarshal([]byte(pathTreeData), &pathRoot) 113 if err != nil { 114 panic(err) 115 } 116 }