• How to show logs?


    Hi all!

    Since many people want or are asked to send some logs (for e.g. finding more info about errors), I created a few bash scripts that can help you send the logs to the internet.

    Here are some examples how to use the scripts (they all start with log_ prefix):

    # Use a temporary log file before sending to the internet:
    rm -f log.txt              # Remove possible old logs!
    log_lspci       log.txt    # Add lspci output to a log file.
    log_xorg        log.txt    # Add xorg log to a log file.
    log_journal     log.txt    # Add journal to a log file.
    log_cmd lsusb   log.txt    # Add lsusb output to a log file.
    log_file        log.txt    # Send all added logs to the internet.
    rm -f log.txt              # Cleanup.
    
    # Send directly to the internet:
    log_journal                   # Send journal to the internet.
    log_file /var/log/Xorg.0.log  # Send xorg log to the internet.
    

    As I see it, there are some benefits to using these scripts:

    • it makes sending logs easy
    • they formalize the way logs are managed
    • they save some info about the sent material, so you can check what you did
    • they are able to hide some user information before sending to the internet
    • they can be expanded to other logging requirements if needed

    Below are the scripts. To have the scripts available to you, either

    • copy them to your ~/.bashrc file (the easiest way)
    • write them to another file, e.g. ~/logs.bash, and use it when needed by running
      source ~/logs.bash
    #!/bin/bash
    
    _log_pipe_to_net()
    {
        # Paste output from pipe to net, and store info about this event.
    
        local cmd="$1"     # Used only for storing info about this event.
        local url
        local storefile="$HOME/.sent_antergos_logs.txt"
    
        if [ -z "$cmd" ] ; then
            cmd="[no command info available]"
        fi
    
        url=$(curl -F [email protected] https://ptpb.pw/?u=1)
    
        # Info (date|url|command) about all sent logs is stored
        # to your $storefile.
        echo "$(date "+%Y%m%d-%H:%M")|$url|$cmd" >> $storefile
    
        echo -n "Logs are here: " >&2
        echo "$url"
    }
    
    _log_header()
    {
        local cmd="$1"
        local sep_line sep_char="="
    
        sep_line="$(printf "$sep_char"'%.s' {1..60})"            # faster
       #sep_line="$(printf "%60s" | tr " " "$sep_char")"         # more standard
    
        printf "\n%s\n%s\n%s\n\n" "$sep_line" "$cmd" "$sep_line"
    }
    
    _log_hide_info()
    {
        local logfile="$1"
        local tmpfile="$logfile"-$$.tmp
    
        mv "$logfile" "$tmpfile"
        cat "$tmpfile" | sed -e 's|'$LOGNAME'|_logname_|g' \
                             -e 's|'$USER'|_user_|g' \
                             -e 's|'$HOSTNAME'|_hostname_|g' \
                             > "$logfile"
        rm -f "$tmpfile"
    }
    
    log_cmd()
    {
        # Add the output of a command to the given file or to the internet.
    
        local cmd="$1"
        local logfile="$2"   # If not given, output is copied to the internet.
        local result=0
    
        if [ -n "$logfile" ] ; then
            if [ ! -f "$logfile" ] ; then
                touch "$logfile"      # Log file doesn't exist, try to create it.
            fi
            if [ -w "$logfile" ] ; then
                _log_header "$cmd" >> "$logfile"
                $cmd >> "$logfile"
                _log_hide_info "$logfile"   # could be removed?
            else
                echo "Error ($FUNCNAME): no permissions to write to logfile '$logfile'." >&2
            fi
        else
            # Output goes to the internet. The returned URL tells where it can be found.
            logfile=/tmp/log-$$.txt
            _log_header "$cmd" >> $logfile
            $cmd >> $logfile
            _log_hide_info "$logfile"
            cat $logfile | _log_pipe_to_net "$cmd"
            rm -f $logfile
        fi
    }
    
    log_file()
    {
        # Copy the file contents to a log file (if given) or to the internet.
    
        local file="$1"
        local logfile="$2"   # If not given, $file contents are copied to the internet.
    
        if [ -r "$file" ] ; then
            log_cmd "cat $file" "$logfile"
        else
            echo "Error ($FUNCNAME): cannot read file '$file'." >&2
        fi
    }
    
    # Helpers for specific commands:
    log_journal() { log_cmd "journalctl -b -0" "$1" ; }
    log_xorg()    { log_file /var/log/Xorg.0.log "$1" ; }
    log_lspci()   { log_cmd "lspci -vnn" "$1" ; }
    
  • @manuel said in How to show logs?:

    log_file log.txt # Send all added logs to the internet.

    how it is doing this?

    Nice script but may caused by yesterday “schaschlik” cook off my head is not fully functional today, i do not get how to use the script…

  • @joekamprad
    It is related to the previous commands in the example:

    log_lspci       log.txt    # Add lspci output to a log file.
    log_xorg        log.txt    # Add xorg log to a log file.
    log_journal     log.txt    # Add journal to a log file.
    log_cmd lsusb   log.txt    # Add lsusb output to a log file.
    

    Each of the above commands put their stuff into the same log file log.txt.
    Then the last command:

    log_file        log.txt    # Send all added logs to the internet.
    

    just sends the contents of log.txt to the internet (pastebin etc.) and the URL returns.

    The most complicated function is log_cmd(). It checks it arguments and determines if the user wanted to just add more stuff to the given logfile, or send the output of one command to the internet.
    Then log_file sends the contents of the given log file to the internet.

    The first example should now make more sense, with this explanation.

    In the second example (user visible) log files are not used at all. The two separate example commands just directly send their stuff to the internet.

    All of these commands (or functions) work together. Always when sending stuff to the internet, the send event is recorded to a file in user’s $HOME directory.
    Then user may later see what events she/he has done before.

  • @joekamprad
    There could be a function like log_all() that would combine all the other functions and simply send the whole log stuff.
    Do you think it would be better that way?

  • how exactly i can execute differend commands and options?

  • Here’s some documentation.

    Definitions

    Lets define a simple concept, the “sink”. Here it means the place where the output of the commands are directed. A sink here is either

    • a log file on your local system, or
    • a place on the internet (like a pastebin URL)

    All functions put their output to the “sink”.

    The input to the functions is either

    • a given command whose output goes to the “sink”
    • another file that will be copied to the “sink”

    In a function call, the user gives the input (a command string or a file name), and optionally the log file, if user wants that to be the sink.

    Basic functions

    There are two basic functions that handle most of the work.
    Their names and parameters are:

    log_cmd - puts the output of a command to the sink

    • command: A command string, e.g. “lspci -vnn”, its output goes to the sink.
    • logfile: Name of the log file (optional).

    log_file - copies the contents of the input file to the sink

    • inputfile: File to be copied to the sink.
    • logfile: Name of the log file (optional).

    Now you can use them in many ways:

    log_cmd "lspci -vnn"
    log_cmd "lspci -vnn" log.txt
    
    log_file /var/log/Xorg.0.log
    log_file /var/log/Xorg.0.log log.txt
    

    The two log_cmd commands have the same input, but the first has internet as the sink. The second has a log file as the sink.

    Also, the two log_file have the same input, but the output goes to the internet with the first, and to the log file with the second.

    So log files (the user gives their names) can be used as a temporary storage when putting many different things to a log file. Then, to put the logs to the internet, the last command typically could be:

    log_file log.txt
    

    without the optional second parameter (now the log.txt in the input to the command, and the sink will be the internet!)

    Helper functions

    Then there are a few “helper” functions, which take only one parameter (the optional log file). And again, if the log file is not given, the output goes directly to the internet instead of a log file.

    log_journal - Puts the output of a “journalctl -b -0” command to the sink.

    • logfile: Log file (optional).

    log_xorg - Copies the contents of file /var/log/Xorg.0.log to the sink.

    • logfile: Log file (optional).

    Stored information

    When you send the output to the internet, some info is stored about each send to the file

    $HOME/.sent_antergos_logs.txt
    

    It contains a line for each send (in plain text). Each line contains the following info:

    • date&time
    • returned URL
    • command used

    This allows you to check later what you have sent to the internet.

    Advanced
    

    Then a bit more advanced usage.
    If you want to have more control over the commands and their options, simply use the first function, log_cmd. For example:

    log_cmd "journalctl -b -0 -r --output=short-full"
    # or:
    log_cmd "journalctl -b -0 -r --output=short-full" log.txt
    log_file log.txt
    

    The first log_cmd call sends the output directly to the internet.
    The second log_cmd call puts the output to a log file, and log_file can then be used for sending it to the internet.

    The commands also automatically hide (by overwriting) some of your identifying information, such as user name and the host name.
    Many users (including me) may appreciate also this feature.

  • Now the previous post may seem something like “too long, didn’t read”.

    But actually, the usage of these functions is really simple.

    Cheers! :)

  • @manuel i think you misunderstand my quesion here…

    i want to ask simple how to use the script. what i have to type into the terminal?

  • @joekamprad
    I hope I understand your question correctly. :)

    First you need to save the script into a file, for example ~/logs.bash, then run source ~/logs.bash so that you have the commands available.

    Alternatively, copy the script contents to the end of your ~/.bashrc file and after running source ~/.bashrc you’ll have the commands at your disposal.

    Then you can run the commands/functions as in the examples above.

    For example:

    log_file /var/log/Xorg.0.log
    

    sends that file to the internet to some pastebin service, and shows the URL where it is saved.

    Is this what you are asking?

  • ha yes… but i do use zsh shell ;)

  • @joekamprad
    Just run commands:

    bash
    source ~/logs.bash
    

    and you’re good to go! :)

  • @manuel

    $ log_cmd "journalctl -b -0 -r --output=short-full"
      % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                     Dload  Upload   Total   Spent    Left  Speed
    100  185k  100    21  100  185k     18   159k  0:00:01  0:00:01 --:--:--  159k
    Logs are here: https://ptpb.pw/XXX
    
    
  • @joekamprad
    Oh how naughty… Couldn’t open your XXX files… ;)

  • Classified

  • @joekamprad
    But anyway, did you notice that your user name and host name have been overwritten in the pastebin link?

  • Mon 2018-09-03 21:29:20 CEST _hostname_ kernel: zbud: loaded
    Mon 2018-09-03 21:29:20 CEST _hostname_ kernel: workingset: timestamp_bits=41 max_order=21 bucket_order=0
    Mon 2018-09-03 21:29:20 CEST _hostname_ kernel: Key type blacklist registered
    
show24 logs16 Posts 17Views 469
Log in to reply
Bloom Email Optin Plugin

Looks like your connection to Antergos Community Forum was lost, please wait while we try to reconnect.