Preserve colors of heroku logs output when piping to other command (e.g. grep) - colors

I am using grep to remove a lot of log noise generated e.g. by NewRelic. I do so using the following command:
heroku logs --force-colors -t -a myApp -s app | grep --color=never web.1
Unfortunately the useful coloring of the logs gets lost somewhere, and the output is uncolored.
The --force-colors flag should force the heroku logs command to output colors even when pipping the output elsewhere. the --color=never flag is supposed to force grep not to use their own coloring scheme.
I have tried all possible combinations with absence or presence of these two color flags, to no avail. Does anybody have a suggestion on how to solve this issue?

I have found a solution here:
script -q /dev/null heroku logs --force-colors -t -a myApp -s app | grep --color=never web.1
The color flags are no even necessary so this works as well:
script -q /dev/null heroku logs -t -a myApp -s app | grep web.1

Related

How to redirect docker logs with grep command to a text file? [duplicate]

This question already has answers here:
How to 'grep' a continuous stream?
(13 answers)
Closed 1 year ago.
For finding specific logs from the docker logs, I am using the grep with docker logs as below
docker logs -f docker_container 2>&1 | grep "KafkaRecordGenerator:197"
Which is giving the correct result in the console. I need to redirect these logs to a text file. For that, I used the below command
docker logs -f docker_container 2>&1 | grep "KafkaRecordGenerator:197" >> test.txt
Here the new file test.txt is created but the output is not redirected to the test.txt file. How to redirect the docker logs with grep command to a text file?
As per the anemyte's comment, --line-buffered with grep command fixed my problem. The final command is,
docker logs -f docker_container 2>&1 | grep --line-buffered "KafkaRecordGenerator:197" >> test.txt

All combined docker logs with container name

So I am trying to get the combined output of all the container logs with its container name in a log file
docker logs --tail -3 with container name >> logst.log file.
docker logs takes a single command so you would have to run them for each container. I guess I could do something along:
docker ps --format='{{.Names}}' | xargs -P0 -d '\n' -n1 sh -c 'docker logs "$1" | sed "s/^/$1: /"' _
docker ps --format='{{.Names}}' - print container names
xargs - for input
-d '\n' - for each line
-P0 - execute in parallel with any count of parallel jobs
remove this option if you don't intent to do docker logs --follow
it may cause problems, consider adding stdbuf -oL and sed -u to unbuffer the streams
-n1 - pass one argument to the underyling process
sh -c 'script' _ - execute script for each line with line passed as first positional argument
docker logs "$1" - get the logs
sed 's/^/$1: /' - prepend the name of the docker name to each log line
But a way better and industrial grade solution would be to forward docker logs to journalctl or other logging solution and use that utility to aggregate and filter logs.
Got it.
for i in docker ps -a -q --format "table {{.ID}}"; do { docker ps -a -q --format "table {{.ID}}\t{{.Names}}\n" | grep "$i" & docker logs --timestamps --tail 1 "$i"; } >> logs.log; done
logs.log is a generic file name.

How can I make an alias for this command piping docker-compose logs -f into less?

I have a working command which I would like to make an alias for, but can't seem to figure out how to do. The working command is
docker-compose logs -f | less -S -R +F
This works fine, essentially removing word wrap from the logs.
The caveat is that when using this I also want to be able to optionally add arguments to the middle, to specify the particular service(s) to tail. Making something that end up looking like this
docker-compose logs -f service1 service2 etc... | less -S -R +F
To be able to do this I was thinking I could use xargs -I to pass in a variable number of arguments and inject them into the middle of the command. But my skill with bash is very limited, and so no matter how much I fiddle with it I can't seem to get it to work, and am sure there is something/some concept I'm missing.
The last iteration of the alias I tried before posting this is
alias logsx="xargs -I{} bash -c 'docker-compose logs -f \"{}\" | less -S -R +F'"
which when you run it seems to start less but without the docker logs being piped there.
Any help would be greatly appreciated. Thanks!
All you need is a function instead.
logsx() {
docker-compose logs -f "$#" | less -S -R +F
}
"$#" will expand the arguments given. So you write logsx service1 service2.

how to get a complete command of X apps via 'wmctl' and 'ps'?

I'm working on a program that can query running X apps, save all the commands of running apps and them reopen them latter.
I encounter an issue. wmctctl can query the pid of Onlyoffice, for example the pid is 123. Then run ps -ef -q 123, I see that the CMD is ./DesktopEditors which should be a invalid command, because ./one_command only can work in special folder include file one_command.
I can get a complete command by running ps -ef -q $(pgrep -P 123).
Is there a straight way to get the complete command of Onlyoffice just via wmctl and ps?
If there is a better way to get all commands of X apps, please let me know. Thanks.
I suggest using ps -h -e -o pid,args command piped with a grep
This should provide full command path with it arguments and options.
For example find all running java programs with their arguments (might be extensive):
ps -eo pid,args | grep java
In your case I suggest a small awk script, that looks for the pid given as 3rd input field in current line:
wmctrl -l -p|awk '{system("ps -h --pid "$3" -o args")}'
Sample output
nautilus-desktop --force
/usr/libexec/gnome-terminal-server
/usr/libexec/gnome-terminal-server
update
Transforming current directory ./ to to full path.
Assuming ./ represent the current working directory.
Add the following pipe.
wmctrl -l -p|awk '{system("ps -h --pid "$3" -o args")}'|sed "s|^\./|$PWD/|"
Find the script or program DesktopEditors in your computer, using find / -name "DesktopEditors".
But I believe this is useless if you are trying to reverse engineer a web based application that requires some kind of a browser emulator.

How to store value from grep output in variable

I am working on one bash script, in which I have to use the regular expression to match string and then store the output in a variable to reuse it.
here is my script,
#!/bin/sh
NAME="MET-3-get-code-from-string"
por="$($NAME | grep -P -o -e '(?<=MET-).*?(\d+)')" #this should store 3 in variable por
echo $por
I tried this many ways, but I am getting error :
./check.sh: MET-3-get-issue-id-from-branch-name: not found
if I run individual grep command then yes, it is working properly. But I am not able to store output.
I also tried :
por=$($NAME | grep -P -o -e '(?<=MET-).*?(\d+)')
por=$NAME | grep -P -o -e '(?<=MET-).*?(\d+)'
and many other similar references.
but it's not working. can anyone please help me on this. I have not much experience in bash.
thank you.
Change
por="$($NAME | grep -P -o -e '(?<=MET-).*?(\d+)')"
to
por="$(echo "$NAME" | grep -P -o -e '(?<=MET-).*?(\d+)')"
Also, you are missing a closing double quote (maybe just a typo, should be NAME="MET-3-get-code-from-string")

Resources