func timeTrack(start time.Time) {
	elapsed := time.Since(start)
	prettyPrintLn(info, fmt.Sprintf("Completed in %s\n", elapsed))
}
Used to track how long the execution takes
package main
import (
	"flag"
	"fmt"
	"log"
	"net/http"
	"strconv"
	"strings"
	"time"
	"github.com/davecgh/go-spew/spew"
)
func prettyPrintLn(logType LogType, msg string) {
	switch logType {
	case debug:
		if Debug {
			log.Printf("%s: %s\n", cyan("[D]"), msg)
		}
	case info:
		log.Printf("%s: %s\n", "[*]", msg)
	case goodnews:
		log.Printf("%s: %s\n", green("[+]"), msg)
	case badnews:
		log.Printf("%s: %s\n", yellow("[-]"), msg)
	case profit:
		log.Printf("%s: %s", green("[$]"), msg)
	case warning:
		log.Printf("%s: %s\n", yellow("[-]"), msg)
	case err:
		log.Printf("%s: %s\n", red("[X]"), msg)
	}
}
func parseCommandLineArgs() *Configuration {
	networkUnparsed := flag.String("target", "", "The target network range in CIDR notation, e.g. 10.10.10.0/24")
	portsUnparsed := flag.String("ports", "8080,8443,80,443,8000,8888", "Comma separated list of target ports.")
	managerPathUnparsed := flag.String("managerpath", "/manager/html", "Manager path.")
	goroutines := flag.Uint("concurrency", 100, "Concurrent Goroutines to use. Due to kernel limitations on linux, it should not be more than 'ulimit -n / 7'.")
	userfile := flag.String("userfile", "", "A file containing user names to test. Requires also a passfile. If neither user-, password- and userpass list is given, the default lists from Metasploit project are used.")
	passfile := flag.String("passfile", "", "A file containing passwords to test. Requires also a userfile. If neither user-, password- and userpass list is given, the default lists from Metasploit project are used.")
	userpassfile := flag.String("userpassfile", "", "A file containing username:password combinations. If neither user-, password- and userpass list is given, the default lists from Metasploit project are used.")
	timeout := flag.Duration("timeout", 2*time.Second, "HTTP timeout. Specify with unit suffix, e.g. '2500ms' or '3s'.")
	avoidLockout := flag.Bool("avoid-lockout", false, "Try to avoid lockout by waiting Tomcat's default lockout treshold between tries. Your scan may get suuuper slow, but in the end, success matters.")
	ignoreInsecure := flag.Bool("ignoreInsecure", true, "Ignore certificate errors. If you only want secure connections, set this to false.")
	flag.BoolVar(&Debug, "debug", false, "Enable debugging output.")
	flag.Parse()
	networkIterator, e := NewNetIterator(*networkUnparsed)
	if e != nil {
		prettyPrintLn(err, e.Error())
	}
	managerPath := parseStringToManagerPath(*managerPathUnparsed)
	ports := parseStringToPorts(*portsUnparsed)
	guesses := buildGuesses(*userfile, *passfile, *userpassfile)
	config := NewConfiguration(networkIterator, ports, guesses, managerPath, *goroutines, *timeout, *avoidLockout, *ignoreInsecure)
	prettyPrintLn(info, fmt.Sprintf("Manager path: %s", managerPath))
	prettyPrintLn(info, fmt.Sprintf("Debug is on: %t", Debug))
	prettyPrintLn(debug, fmt.Sprintf("Goroutines to use: %d", *goroutines))
	return config
}
func parseStringToManagerPath(rawString string) string {
	if strings.HasPrefix(rawString, "/") {
		return rawString
	}
	return "/" + rawString
}
func parseStringToPorts(rawString string) []uint {
	portStringSplitted := strings.Split(rawString, ",")
	portSlice := make([]uint, 0)
	for i := 0; i < len(portStringSplitted); i++ {
		val, _ := strconv.ParseUint(portStringSplitted[i], 10, 16)
		portSlice = append(portSlice, uint(val))
	}
	return portSlice
}