github.com/google/cadvisor@v0.49.1/perf/config.go (about) 1 // Copyright 2020 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 // Configuration for perf event manager. 16 package perf 17 18 import ( 19 "encoding/json" 20 "fmt" 21 "os" 22 "strconv" 23 24 "k8s.io/klog/v2" 25 ) 26 27 type PerfEvents struct { 28 // Core perf events to be measured. 29 Core Events `json:"core,omitempty"` 30 31 // Uncore perf events to be measured. 32 Uncore Events `json:"uncore,omitempty"` 33 } 34 35 type Events struct { 36 // List of perf events' names to be measured. 37 Events []Group `json:"events"` 38 39 // List of custom perf events' to be measured. It is impossible to 40 // specify some events using their names and in such case you have 41 // to provide lower level configuration. 42 CustomEvents []CustomEvent `json:"custom_events"` 43 } 44 45 type Event string 46 47 type CustomEvent struct { 48 // Type of the event. See perf_event_attr documentation 49 // at man perf_event_open. 50 Type uint32 `json:"type,omitempty"` 51 52 // Symbolically formed event like: 53 // pmu/config=PerfEvent.Config[0],config1=PerfEvent.Config[1],config2=PerfEvent.Config[2] 54 // as described in man perf-stat. 55 Config Config `json:"config"` 56 57 // Human readable name of metric that will be created from the event. 58 Name Event `json:"name"` 59 } 60 61 type Config []uint64 62 63 func (c *Config) UnmarshalJSON(b []byte) error { 64 config := []string{} 65 err := json.Unmarshal(b, &config) 66 if err != nil { 67 klog.Errorf("Unmarshalling %s into slice of strings failed: %q", b, err) 68 return fmt.Errorf("unmarshalling %s into slice of strings failed: %q", b, err) 69 } 70 intermediate := []uint64{} 71 for _, v := range config { 72 uintValue, err := strconv.ParseUint(v, 0, 64) 73 if err != nil { 74 klog.Errorf("Parsing %#v into uint64 failed: %q", v, err) 75 return fmt.Errorf("parsing %#v into uint64 failed: %q", v, err) 76 } 77 intermediate = append(intermediate, uintValue) 78 } 79 *c = intermediate 80 return nil 81 } 82 83 func parseConfig(file *os.File) (events PerfEvents, err error) { 84 decoder := json.NewDecoder(file) 85 err = decoder.Decode(&events) 86 if err != nil { 87 err = fmt.Errorf("unable to load perf events configuration from %q: %q", file.Name(), err) 88 return 89 } 90 return 91 } 92 93 type Group struct { 94 events []Event 95 array bool 96 } 97 98 func (g *Group) UnmarshalJSON(b []byte) error { 99 var jsonObj interface{} 100 err := json.Unmarshal(b, &jsonObj) 101 if err != nil { 102 return err 103 } 104 switch obj := jsonObj.(type) { 105 case string: 106 *g = Group{ 107 events: []Event{Event(obj)}, 108 array: false, 109 } 110 return nil 111 case []interface{}: 112 group := Group{ 113 events: make([]Event, 0, len(obj)), 114 array: true, 115 } 116 for _, v := range obj { 117 value, ok := v.(string) 118 if !ok { 119 return fmt.Errorf("cannot unmarshal %v", value) 120 } 121 group.events = append(group.events, Event(value)) 122 } 123 *g = group 124 return nil 125 } 126 return fmt.Errorf("unsupported type") 127 }