mirror of
https://github.com/k3s-io/k3s.git
synced 2024-06-07 19:41:36 +00:00
c6950d2cb0
Signed-off-by: Brad Davidson <brad.davidson@rancher.com>
128 lines
3.2 KiB
Go
128 lines
3.2 KiB
Go
// Copyright 2020 Google Inc. All Rights Reserved.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
// Configuration for perf event manager.
|
|
package perf
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"os"
|
|
"strconv"
|
|
|
|
"k8s.io/klog/v2"
|
|
)
|
|
|
|
type PerfEvents struct {
|
|
// Core perf events to be measured.
|
|
Core Events `json:"core,omitempty"`
|
|
|
|
// Uncore perf events to be measured.
|
|
Uncore Events `json:"uncore,omitempty"`
|
|
}
|
|
|
|
type Events struct {
|
|
// List of perf events' names to be measured.
|
|
Events []Group `json:"events"`
|
|
|
|
// List of custom perf events' to be measured. It is impossible to
|
|
// specify some events using their names and in such case you have
|
|
// to provide lower level configuration.
|
|
CustomEvents []CustomEvent `json:"custom_events"`
|
|
}
|
|
|
|
type Event string
|
|
|
|
type CustomEvent struct {
|
|
// Type of the event. See perf_event_attr documentation
|
|
// at man perf_event_open.
|
|
Type uint32 `json:"type,omitempty"`
|
|
|
|
// Symbolically formed event like:
|
|
// pmu/config=PerfEvent.Config[0],config1=PerfEvent.Config[1],config2=PerfEvent.Config[2]
|
|
// as described in man perf-stat.
|
|
Config Config `json:"config"`
|
|
|
|
// Human readable name of metric that will be created from the event.
|
|
Name Event `json:"name"`
|
|
}
|
|
|
|
type Config []uint64
|
|
|
|
func (c *Config) UnmarshalJSON(b []byte) error {
|
|
config := []string{}
|
|
err := json.Unmarshal(b, &config)
|
|
if err != nil {
|
|
klog.Errorf("Unmarshalling %s into slice of strings failed: %q", b, err)
|
|
return fmt.Errorf("unmarshalling %s into slice of strings failed: %q", b, err)
|
|
}
|
|
intermediate := []uint64{}
|
|
for _, v := range config {
|
|
uintValue, err := strconv.ParseUint(v, 0, 64)
|
|
if err != nil {
|
|
klog.Errorf("Parsing %#v into uint64 failed: %q", v, err)
|
|
return fmt.Errorf("parsing %#v into uint64 failed: %q", v, err)
|
|
}
|
|
intermediate = append(intermediate, uintValue)
|
|
}
|
|
*c = intermediate
|
|
return nil
|
|
}
|
|
|
|
func parseConfig(file *os.File) (events PerfEvents, err error) {
|
|
decoder := json.NewDecoder(file)
|
|
err = decoder.Decode(&events)
|
|
if err != nil {
|
|
err = fmt.Errorf("unable to load perf events configuration from %q: %q", file.Name(), err)
|
|
return
|
|
}
|
|
return
|
|
}
|
|
|
|
type Group struct {
|
|
events []Event
|
|
array bool
|
|
}
|
|
|
|
func (g *Group) UnmarshalJSON(b []byte) error {
|
|
var jsonObj interface{}
|
|
err := json.Unmarshal(b, &jsonObj)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
switch obj := jsonObj.(type) {
|
|
case string:
|
|
*g = Group{
|
|
events: []Event{Event(obj)},
|
|
array: false,
|
|
}
|
|
return nil
|
|
case []interface{}:
|
|
group := Group{
|
|
events: make([]Event, 0, len(obj)),
|
|
array: true,
|
|
}
|
|
for _, v := range obj {
|
|
value, ok := v.(string)
|
|
if !ok {
|
|
return fmt.Errorf("cannot unmarshal %v", value)
|
|
}
|
|
group.events = append(group.events, Event(value))
|
|
}
|
|
*g = group
|
|
return nil
|
|
}
|
|
return fmt.Errorf("unsupported type")
|
|
}
|