github.com/google/cadvisor@v0.49.1/perf/manager_libpfm.go (about)

     1  //go:build libpfm && cgo
     2  // +build libpfm,cgo
     3  
     4  // Copyright 2020 Google Inc. All Rights Reserved.
     5  //
     6  // Licensed under the Apache License, Version 2.0 (the "License");
     7  // you may not use this file except in compliance with the License.
     8  // You may obtain a copy of the License at
     9  //
    10  //     http://www.apache.org/licenses/LICENSE-2.0
    11  //
    12  // Unless required by applicable law or agreed to in writing, software
    13  // distributed under the License is distributed on an "AS IS" BASIS,
    14  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    15  // See the License for the specific language governing permissions and
    16  // limitations under the License.
    17  
    18  // Manager of perf events for containers.
    19  package perf
    20  
    21  import (
    22  	"fmt"
    23  	"os"
    24  
    25  	info "github.com/google/cadvisor/info/v1"
    26  	"github.com/google/cadvisor/stats"
    27  	"github.com/google/cadvisor/utils/sysinfo"
    28  )
    29  
    30  type manager struct {
    31  	events      PerfEvents
    32  	onlineCPUs  []int
    33  	cpuToSocket map[int]int
    34  	stats.NoopDestroy
    35  }
    36  
    37  func NewManager(configFile string, topology []info.Node) (stats.Manager, error) {
    38  	if configFile == "" {
    39  		return &stats.NoopManager{}, nil
    40  	}
    41  
    42  	file, err := os.Open(configFile)
    43  	if err != nil {
    44  		return nil, fmt.Errorf("unable to read configuration file %q: %w", configFile, err)
    45  	}
    46  
    47  	config, err := parseConfig(file)
    48  	if err != nil {
    49  		return nil, fmt.Errorf("unable to parse configuration file %q: %w", configFile, err)
    50  	}
    51  
    52  	if len(config.Core.Events) == 0 && len(config.Uncore.Events) == 0 {
    53  		return nil, fmt.Errorf("there is no events in config file %q", configFile)
    54  	}
    55  
    56  	onlineCPUs := sysinfo.GetOnlineCPUs(topology)
    57  
    58  	cpuToSocket := make(map[int]int)
    59  
    60  	for _, cpu := range onlineCPUs {
    61  		cpuToSocket[cpu] = sysinfo.GetSocketFromCPU(topology, cpu)
    62  	}
    63  
    64  	return &manager{events: config, onlineCPUs: onlineCPUs, cpuToSocket: cpuToSocket}, nil
    65  }
    66  
    67  func (m *manager) GetCollector(cgroupPath string) (stats.Collector, error) {
    68  	collector := newCollector(cgroupPath, m.events, m.onlineCPUs, m.cpuToSocket)
    69  	err := collector.setup()
    70  	if err != nil {
    71  		collector.Destroy()
    72  		return &stats.NoopCollector{}, err
    73  	}
    74  	return collector, nil
    75  }