<commit_before>/*
   Copyright (c) 2016, Percona LLC and/or its affiliates. All rights reserved.

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU Affero General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU Affero General Public License for more details.

   You should have received a copy of the GNU Affero General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>
*/

package main

import (
	"encoding/json"
	"flag"
	"fmt"
	golog "log"
	"os"
	"os/signal"
	"os/user"
	"runtime"
	"syscall"
	"time"

	"github.com/percona/pmm/proto"
	pc "github.com/percona/pmm/proto/config"
	"github.com/percona/qan-agent/agent"
	"github.com/percona/qan-agent/agent/release"
	"github.com/percona/qan-agent/client"
	"github.com/percona/qan-agent/data"
	"github.com/percona/qan-agent/instance"
	"github.com/percona/qan-agent/log"
	"github.com/percona/qan-agent/mrms"
	"github.com/percona/qan-agent/mysql"
	"github.com/percona/qan-agent/pct"
	pctCmd "github.com/percona/qan-agent/pct/cmd"
	"github.com/percona/qan-agent/qan"
	qanAnalyzerFactory "github.com/percona/qan-agent/qan/analyzer/factory"
	"github.com/percona/qan-agent/query"
	"github.com/percona/qan-agent/ticker"
)

var (
	flagBasedir string
	flagPidFile string
	flagListen  string
	flagPing    bool
	flagVersion bool
)

func init() {
	if os.Getenv("GOMAXPROCS") == "" {
		runtime.GOMAXPROCS(1)
	}

	golog.SetFlags(golog.Ldate | golog.Ltime | golog.Lmicroseconds | golog.Lshortfile)
	golog.SetOutput(os.Stdout)

	// PMM-1842: TODO: pid-file is now dummy flag to keep backward compatibility, it's not used anymore.
	// Remove it after we decide v1.0.5 is old enough to not be supported.
	// https://github.com/percona/pmm-client/commit/2dd9f028e6f8930f9f0185d13f2053d3683b8e64#diff-10f4cb4dc1c681a08cdba7b20c30b3f1
	flag.StringVar(&flagPidFile, "pid-file", "", "PID file")

	flag.StringVar(&flagBasedir, "basedir", pct.DEFAULT_BASEDIR, "Agent basedir")
	flag.StringVar(&flagListen, "listen", agent.DEFAULT_LISTEN, "Agent interface address")
	flag.BoolVar(&flagPing, "ping", false, "Ping API")
	flag.BoolVar(&flagVersion, "version", false, "Print version")

	flag.Parse()

	// We don't accept any positional arguments
	if len(flag.Args()) != 0 {
		flag.Usage()
		os.Exit(1)
	}
}

func main() {
	// //////////////////////////////////////////////////////////////////////
	// Handle options like -version which don't start the agent.
	// //////////////////////////////////////////////////////////////////////

	agentVersion := fmt.Sprintf("percona-qan-agent %s", release.VERSION)
	if flagVersion {
		fmt.Println(agentVersion)
		return
	}

	if err := pct.Basedir.Init(flagBasedir); err != nil {
		fmt.Printf("Error initializing basedir %s: %s", flagBasedir, err)
		os.Exit(1)
	}

	// Read agent.conf to get API hostname and agent UUID.
	agentConfigFile := pct.Basedir.ConfigFile("agent")
	if !pct.FileExists(agentConfigFile) {
		fmt.Printf("Agent config file %s does not exist", agentConfigFile)
		os.Exit(1)
	}

	bytes, err := agent.LoadConfig()
	if err != nil {
		fmt.Printf("Error reading agent config file %s: %s", agentConfigFile, err)
		os.Exit(1)
	}
	agentConfig := &pc.Agent{}
	if err := json.Unmarshal(bytes, agentConfig); err != nil {
		fmt.Printf("Error decoding agent config file %s: %s", agentConfigFile, err)
		os.Exit(1)
	}

	apiURL := agentConfig.ApiHostname + agentConfig.ApiPath
	fmt.Printf("# Version: %s\n", agentVersion)
	fmt.Printf("# Basedir: %s\n", pct.Basedir.Path())
	//fmt.Printf("# Listen:  %s\n", flagListen)
	fmt.Printf("# PID:     %d\n", os.Getpid())
	fmt.Printf("# API:     %s\n", apiURL)
	fmt.Printf("# UUID:    %s\n", agentConfig.UUID)

	// -ping and exit.
	if flagPing {
		t0 := time.Now()
		code, err := pct.Ping(apiURL)
		d := time.Now().Sub(t0)
		if err != nil || code != 200 {
			fmt.Printf("Ping FAIL (%d %d %s)", d, code, err)
			os.Exit(1)
		}
		fmt.Printf("Ping OK (%s)", d)
		return
	}

	// //////////////////////////////////////////////////////////////////////
	// Run the agent
	// //////////////////////////////////////////////////////////////////////

	err = run(agentConfig) // run the agent

	if err != nil {
		golog.Println(err)
		os.Exit(1)
	}
}

func run(agentConfig *pc.Agent) error {
	golog.Println("Starting agent...")
	var stopErr error
	defer func() {
		if stopErr == nil {
			golog.Println("Agent has stopped")
		}
	}()
<commit_msg>PMM-2615 Add newlines to logs.<commit_after>/*
   Copyright (c) 2016, Percona LLC and/or its affiliates. All rights reserved.

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU Affero General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU Affero General Public License for more details.

   You should have received a copy of the GNU Affero General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>
*/

package main

import (
	"encoding/json"
	"flag"
	"fmt"
	golog "log"
	"os"
	"os/signal"
	"os/user"
	"runtime"
	"syscall"
	"time"

	"github.com/percona/pmm/proto"
	pc "github.com/percona/pmm/proto/config"
	"github.com/percona/qan-agent/agent"
	"github.com/percona/qan-agent/agent/release"
	"github.com/percona/qan-agent/client"
	"github.com/percona/qan-agent/data"
	"github.com/percona/qan-agent/instance"
	"github.com/percona/qan-agent/log"
	"github.com/percona/qan-agent/mrms"
	"github.com/percona/qan-agent/mysql"
	"github.com/percona/qan-agent/pct"
	pctCmd "github.com/percona/qan-agent/pct/cmd"
	"github.com/percona/qan-agent/qan"
	qanAnalyzerFactory "github.com/percona/qan-agent/qan/analyzer/factory"
	"github.com/percona/qan-agent/query"
	"github.com/percona/qan-agent/ticker"
)

var (
	flagBasedir string
	flagPidFile string
	flagListen  string
	flagPing    bool
	flagVersion bool
)

func init() {
	if os.Getenv("GOMAXPROCS") == "" {
		runtime.GOMAXPROCS(1)
	}

	golog.SetFlags(golog.Ldate | golog.Ltime | golog.Lmicroseconds | golog.Lshortfile)
	golog.SetOutput(os.Stdout)

	// PMM-1842: TODO: pid-file is now dummy flag to keep backward compatibility, it's not used anymore.
	// Remove it after we decide v1.0.5 is old enough to not be supported.
	// https://github.com/percona/pmm-client/commit/2dd9f028e6f8930f9f0185d13f2053d3683b8e64#diff-10f4cb4dc1c681a08cdba7b20c30b3f1
	flag.StringVar(&flagPidFile, "pid-file", "", "PID file")

	flag.StringVar(&flagBasedir, "basedir", pct.DEFAULT_BASEDIR, "Agent basedir")
	flag.StringVar(&flagListen, "listen", agent.DEFAULT_LISTEN, "Agent interface address")
	flag.BoolVar(&flagPing, "ping", false, "Ping API")
	flag.BoolVar(&flagVersion, "version", false, "Print version")

	flag.Parse()

	// We don't accept any positional arguments
	if len(flag.Args()) != 0 {
		flag.Usage()
		os.Exit(1)
	}
}

func main() {
	// //////////////////////////////////////////////////////////////////////
	// Handle options like -version which don't start the agent.
	// //////////////////////////////////////////////////////////////////////

	agentVersion := fmt.Sprintf("percona-qan-agent %s", release.VERSION)
	if flagVersion {
		fmt.Println(agentVersion)
		return
	}

	if err := pct.Basedir.Init(flagBasedir); err != nil {
		fmt.Printf("Error initializing basedir %s: %s\n", flagBasedir, err)
		os.Exit(1)
	}

	// Read agent.conf to get API hostname and agent UUID.
	agentConfigFile := pct.Basedir.ConfigFile("agent")
	if !pct.FileExists(agentConfigFile) {
		fmt.Printf("Agent config file %s does not exist\n", agentConfigFile)
		os.Exit(1)
	}

	bytes, err := agent.LoadConfig()
	if err != nil {
		fmt.Printf("Error reading agent config file %s: %s\n", agentConfigFile, err)
		os.Exit(1)
	}
	agentConfig := &pc.Agent{}
	if err := json.Unmarshal(bytes, agentConfig); err != nil {
		fmt.Printf("Error decoding agent config file %s: %s\n", agentConfigFile, err)
		os.Exit(1)
	}

	apiURL := agentConfig.ApiHostname + agentConfig.ApiPath
	fmt.Printf("# Version: %s\n", agentVersion)
	fmt.Printf("# Basedir: %s\n", pct.Basedir.Path())
	//fmt.Printf("# Listen:  %s\n", flagListen)
	fmt.Printf("# PID:     %d\n", os.Getpid())
	fmt.Printf("# API:     %s\n", apiURL)
	fmt.Printf("# UUID:    %s\n", agentConfig.UUID)

	// -ping and exit.
	if flagPing {
		t0 := time.Now()
		code, err := pct.Ping(apiURL)
		d := time.Now().Sub(t0)
		if err != nil || code != 200 {
			fmt.Printf("Ping FAIL (%d %d %s)\n", d, code, err)
			os.Exit(1)
		}
		fmt.Printf("Ping OK (%s)\n", d)
		return
	}

	// //////////////////////////////////////////////////////////////////////
	// Run the agent
	// //////////////////////////////////////////////////////////////////////

	err = run(agentConfig) // run the agent

	if err != nil {
		golog.Println(err)
		os.Exit(1)
	}
}

func run(agentConfig *pc.Agent) error {
	golog.Println("Starting agent...")
	var stopErr error
	defer func() {
		if stopErr == nil {
			golog.Println("Agent has stopped")
		}
	}()

{'fraction_non_alphanumeric': 0.19393683321009825, 'fraction_numerical': 0.015421992183373825, 'mean_word_length': 2.88829568788501, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 2, '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': '5259936', 'n_tokens_mistral': 3522, 'n_tokens_neox': 3373, 'n_words': 824}