<commit_before>package utils

import (
	"log"
	"io/ioutil"
	"bytes"
	"os"
	"strings"
	"strconv"
	"io"
	"syscall"
	"path/filepath"
	"github.com/sirupsen/logrus"
)

type TelegrafReloader struct {
	name         string
	signal       syscall.Signal
	shouldReload bool
}

// Create new config and populate it from environment
func NewTelegrafReloader() *TelegrafReloader {
	return &TelegrafReloader{
		signal:       syscall.SIGHUP,
		shouldReload: false,
	}
}

func (tr *TelegrafReloader) Name() string {
	return tr.name
}

func (tr *TelegrafReloader) IsReloadRequested() bool {
	return tr.shouldReload
}

func (tr *TelegrafReloader) RequestReload() {
	tr.shouldReload = true
}

func (tr *TelegrafReloader) ReloadIfRequested() {
	if tr.shouldReload {
		tr.Reload()
	}
}
func (tr *TelegrafReloader) Reload() {
	tr.dispatchSignal()
	tr.shouldReload = false
}

func (tr *TelegrafReloader) dispatchSignal() {

	callback := func(path string, info os.FileInfo, err error) error {
		// We just return in case of errors, as they are likely due to insufficient
		// privileges. We shouldn't get any errors for accessing the information we
		// are interested in. Run as root (sudo) and log the error, in case you want
		// this information.
		if err != nil {
			return nil
		}

		// We are only interested in files with a path looking like /proc/<pid>/status.
		if strings.Count(path, "/") == 3 && strings.Contains(path, "/status") {

			// Let's extract the middle part of the path with the <pid> and
			// convert the <pid> into an integer. Log an error if it fails.
			pid, err := strconv.Atoi(path[6:strings.LastIndex(path, "/")])
			if err != nil {
				logrus.Debugf("failed to extract pid from path: %v", path)
				return nil
			}

			// The status file contains the name of the process in its first line.
			// The line looks like "Name: theProcess".
			// Log an error in case we cant read the file.
			f, err := ioutil.ReadFile(path)
			if err != nil {
				log.Println(err)
				return nil
			}

			// Extract the process name from within the first line in the buffer
			name := string(f[6:bytes.IndexByte(f, '\n')])

			if name == tr.name {
				logrus.Debugf("PID: %d, Name: %s will be signaled with %v", pid, name, tr.signal)
				proc, err := os.FindProcess(pid)
				if err != nil {
					logrus.Errorf("> Failed to signal, err: %v", err)
					log.Println(err)
				}

				proc.Signal(tr.signal)

				// Let's return a fake error to abort the walk through the rest of the /proc directory tree
				return io.EOF
			}
		}<commit_msg>improved reloader description<commit_after>package utils

import (
	"log"
	"io/ioutil"
	"bytes"
	"os"
	"strings"
	"strconv"
	"io"
	"syscall"
	"path/filepath"
	"github.com/sirupsen/logrus"
)

type TelegrafReloader struct {
	name         string
	signal       syscall.Signal
	shouldReload bool
}

// Create new config and populate it from environment
func NewTelegrafReloader() *TelegrafReloader {
	return &TelegrafReloader{
		signal:       syscall.SIGHUP,
		shouldReload: false,
	}
}

func (tr *TelegrafReloader) Name() string {
	return tr.name
}

func (tr *TelegrafReloader) IsReloadRequested() bool {
	return tr.shouldReload
}

func (tr *TelegrafReloader) RequestReload() {
	tr.shouldReload = true
}

func (tr *TelegrafReloader) ReloadIfRequested() {
	if tr.shouldReload {
		tr.Reload()
	}
}
func (tr *TelegrafReloader) Reload() {
	tr.dispatchSignal()
	tr.shouldReload = false
}

func (tr *TelegrafReloader) dispatchSignal() {

	callback := func(path string, info os.FileInfo, err error) error {
		// We just return in case of errors, as they are likely due to insufficient privileges. We shouldn't get any
		// errors for accessing the information we are interested in. Run as root (sudo) and log the error, in case you
		// want this information.
		if err != nil {
			return nil
		}

		// We are only interested in files with a path looking like /proc/<pid>/status.
		if strings.Count(path, "/") == 3 && strings.Contains(path, "/status") {

			// extract the middle part of the path with the <pid> and convert it into an integer. Log on failure
			pid, err := strconv.Atoi(path[6:strings.LastIndex(path, "/")])
			if err != nil {
				logrus.Debugf("failed to extract pid from path: %v", path)
				return nil
			}

			// The status file contains the name of the process in its first line.
			// The line looks like "Name: theProcess", log an error in case we cant read the file.
			f, err := ioutil.ReadFile(path)
			if err != nil {
				logrus.Error("failed to read status file, %+v", err)
				return nil
			}

			// Extract the process name from within the first line in the buffer
			name := string(f[6:bytes.IndexByte(f, '\n')])

			if name == tr.name {
				logrus.Debugf("PID: %d, Name: %s will be signaled with %v", pid, name, tr.signal)
				proc, err := os.FindProcess(pid)
				if err != nil {
					logrus.Errorf("> Failed to signal, err: %v", err)
					log.Println(err)
				}

				proc.Signal(tr.signal)

				// Let's return a fake error to abort the walk through the rest of the /proc directory tree
				return io.EOF
			}
		}
{'fraction_non_alphanumeric': 0.1146471634710417, 'fraction_numerical': 0.0011860051393556038, 'mean_word_length': 3.185277088502895, 'pattern_counts': {'":': 0, '<': 8, '<?xml version=': 0, '>': 10, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, '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': '1052884', 'n_tokens_mistral': 1916, 'n_tokens_neox': 1697, 'n_words': 585}