<commit_before>// Copyright 2014 The Serviced Authors.
// 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.

package cgroup

import (
	"bufio"
	"fmt"
	"io/ioutil"
	"strconv"
	"strings"
	"os"
)

const (
    Cpuacct string = "cpuacct"
    Memory string = "memory"
)

// Helper function that takes a docker ID and parameter (to specify cpu or memory)
// and returns a path to the correct stats file 
func GetCgroupDockerStatsFilePath(dockerID string, stat string) string {
	debFile := "/sys/fs/cgroup/" + stat + "/docker/" + dockerID + "/" + stat + ".stat"
	linFile := "/sys/fs/cgroup/" + stat + "/system.slice/docker-" + dockerID + ".scope/" + stat + ".stat"
	if _, err := os.Stat(debFile); err == nil {
		return debFile
	}
	if _, err := os.Stat(linFile); err == nil {
		return linFile
	}
    return ""
}

// parseSSKVint64 parses a space-separated key-value pair file and returns a
// key(string):value(int64) mapping.
func parseSSKVint64(filename string) (map[string]int64, error) {
	kv, err := parseSSKV(filename)
	if err != nil {
		return nil, err
	}
	mapping := make(map[string]int64)
	for k, v := range kv {
		n, err := strconv.ParseInt(v, 0, 64)
		if err != nil {
			uintVal, uintErr := strconv.ParseUint(v, 0, 64)
			if uintErr == nil {
				// the value is 64-bit unsigned, so we will cast it to a signed 64-bit integer.  This will result
				// in an incorrect value, but will allow us to report other metrics without breaking everything
				n = int64(uintVal)
			} else {
				return nil, err
			}<commit_msg>CC-1901: Be safe about finding host level cgroup metrics<commit_after>// Copyright 2014 The Serviced Authors.
// 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.

package cgroup

import (
	"bufio"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"strconv"
	"strings"
)

const (
	Cpuacct string = "cpuacct"
	Memory  string = "memory"
)

// Helper function that takes a docker ID and parameter (to specify cpu or memory)
// and returns a path to the correct stats file
func GetCgroupDockerStatsFilePath(dockerID string, stat string) string {
	// The location of this is dependent on the cgroup driver that docker is using, as
	// well as the version of Docker being used.  To that end, we'll look at all the known
	// locations, and pick the first one that's populated.
	locations := []string{
		// debian(all docker versions) + rhel(docker 1.10-rc1 [and presumably beyond])
		filepath.Join("/sys/fs/cgroup/", stat, "/docker/", dockerID, stat+".stat"),
		// rhel  (<=1.9.0)
		filepath.Join("/sys/fs/cgroup/", stat, "/system.slice/docker-"+dockerID+".scope/", stat+".stat"),
		// rhel (1.9.0 w/ '--exec-opt native.cgroupdriver=cgroupfs' flag, workaround for docker issue #17653
		filepath.Join("/sys/fs/cgroup/", stat, "/system.slice/docker/", dockerID, stat+".stat"),
	}
	for _, loc := range locations {
		if _, err := os.Stat(loc); err == nil {
			return loc
		}
	}
	return ""
}

// parseSSKVint64 parses a space-separated key-value pair file and returns a
// key(string):value(int64) mapping.
func parseSSKVint64(filename string) (map[string]int64, error) {
	kv, err := parseSSKV(filename)
	if err != nil {
		return nil, err
	}
	mapping := make(map[string]int64)
	for k, v := range kv {
		n, err := strconv.ParseInt(v, 0, 64)
		if err != nil {
			uintVal, uintErr := strconv.ParseUint(v, 0, 64)
			if uintErr == nil {
				// the value is 64-bit unsigned, so we will cast it to a signed 64-bit integer.  This will result
				// in an incorrect value, but will allow us to report other metrics without breaking everything
				n = int64(uintVal)
			} else {
				return nil, err
			}
{'fraction_non_alphanumeric': 0.1205658324265506, 'fraction_numerical': 0.01719260065288357, 'mean_word_length': 3.364672364672365, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '194922', 'n_tokens_mistral': 1576, 'n_tokens_neox': 1437, 'n_words': 562}