4

Coming from shell programming, where i used a lot such function:

log_action() {
case "${1}" in
'ERROR')
    EXIT_CODE="${3}"
    echo "[${1}] | $(date +"%T") | ${2} | Exiting (${EXIT_CODE})"
    exit ${EXIT_CODE};
;;
'WARNING')
    echo "[${1}] | $(date +"%T") | ${2} | Line: (${3})"
;;
'DEBUG')
    if [[ ${DEBUG} -eq "1" ]]; then {
    echo "[${1}] | $(date +"%T") | ${2} | ${3}"
    }; fi
;;
*)
    echo "[${1}] | $(date +"%T") | ${2} | ${3}"
;;
esac
}


log_action "WARNING" "Cannot Connect to MySQL Database" "${LINENO}")

Now, i started to learn golang and will like to convert all bash scripts to go. So, I need the same function to use in golang, i tried the following:

func logHandler(t string, e string, l string) {
    switch t {
    case "warning":
        fmt.Println("WARNING")
    case "error":
        fmt.Println("ERROR")
    case "debug":
        fmt.Println("DEBUG |", e, l)
    }
}

logHandler("debug", "Test Function", "LineNumber")

but i don't know how to get the current linenumber variable (LineNumber) when calling logHandler function and pass it to the function as string or as int.

Also, is there any way to run a go script in trace mode like in bash option: set -o xtrace?

I'm just a beginner so if i'm doing something wrong please point me to the right direction. Thank You.

1
  • 1
    "any way to run a go script" no such thing. Go is not a scripting language. Go is only executable compiled down to a complete native binary. Trying to write Go programs like bash scripts (or anything else besides Go) will only lead to frustration. Commented Jul 17, 2018 at 20:40

1 Answer 1

3

Here's one elegant way you can do it.

We'll be using the runtime package, here's how:

package main

import (
    "fmt"
    "runtime"
)

func main() {
    logHandler("warning", "Test Function")
    logHandler("error", "Test Function")
    logHandler("debug", "Test Function")
}

func logHandler(t, e string) {
    switch t {
    case "warning":
        fmt.Println("WARNING |", e)
    case "error":
        fmt.Println("ERROR   |", e)
    case "debug":
        // 0 = This function
        // 1 = Function that called this function
        _, fn, line, _ := runtime.Caller(1)
        fmt.Printf("DEBUG   | %s:%d | %v\n", fn, line, e)
    }
}

Outputs:

WARNING | Test Function
ERROR   | Test Function
DEBUG   | /home/runner/main.go:11 | Test Function

Working example link


You could basically do this for all of them (warning and debug)

If you're interested here's some additional reading regarding the runtime package.


Inspired by this great answer from OneOfOne.

Sign up to request clarification or add additional context in comments.

3 Comments

Mihailo, your solution is very close to what I'm looking for. Just, by using this method I'm getting the line number inside the logHandler function, but what i'm looking for - is to get it from the main function, so in your example it actually should be number '11' instead of '23'.
Mihailo, Great!, that's exactly what i'm looking for. Thank you a lot!
Great! Glad I could help.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.