How to automatically stop logstash process instance after its read the doc - logstash

I want to ask that, below is my code. With the below code logstash reads the file until its end. Then it is stops reading but process is still alive. I want that process stops when it finishes the reading. How can i do this ?
file {
path => "directory/*.log"
start_position => "beginning"
mode => "read"
}
Thanks for answering

try using the stdin input plugin instead of file input, and passing the file as input in the command for starting logstash.
e.g.
bin/logstash -f readFileFromStdin.conf < /path_to_file/test.log
For multiple files you could do
bin/logstash -f readFileFromStdin.conf < cat /path_to_file/*.log
or
cat /path_to_file/*.log > /tmp/myLogs
bin/logstash -f readFileFromStdin.conf < /tmp/myLogs

Related

How to use set -x without showing stdout?

Within CI, I am running a bash script that calls many bash scripts.
./internals/declination/create "${RELEASE_VERSION}" "${CI_COMMIT_REF_NAME}" > /dev/null
This doest not disable the stdout returned by the script.
The Gitlabi-CI runners stop logging after 100MB of log, It says Job's log exceeded limit of 10240000 bytes.
I know the log script can only grow up.
How can I optimize the output log size?
I don't need to have all the stdout, I can have stderr but then it will be a long running script without information.
Is there a way to display the commands which is running like when doing set -x?
Edit
Reading the answers, I was not able to solve my issue. I need to add that I am using nodejs to run the bash script that run the long bash script.
This is how I call my node script within .gitlab-ci.yml:
scripts:
- node my_script.js
Within my_script.js, I have:
exports.handler = () => {
const ls = spawn('bash', [path.join(__dirname, 'release.sh')], { stdio: 'inherit' });
ls.on('close', (code) => {
if (code !== 0) {
console.log(`ps process exited with code ${code}`);
process.exitCode = code;
}
});
};
Within my_script.sh, I have:
./internals/declination/create "${RELEASE_VERSION}" "${CI_COMMIT_REF_NAME}" > /dev/null
You can selectively redirect file handles with exec.
exec >stdout 2>stderr
This however loses the connection to the terminal, so there is no simple way to output anything to the terminal after this point.
You can instead duplicate a file handle with m>&n where m is the number of the file descriptor to duplicate and n is the number of the new one (choose a big number like 99 to not accidentally clobber an existing handle).
exec 98<&1 # stdout
exec 99<&2 # stderr
exec >/dev/null 2>&1
:
To re-enable output,
exec 1<&98 2<&99
If you redirected to a temporary file instead of /dev/null you could obviously now show the tail of those files to the caller.
tail -n 100 "$TMPDIR"/stdout "$TMPDIR"/stderr
(On a shared server, probably use mktemp to create a unique temporary directory at the beginning of your script; static hard-coded file names make it impossible to run two builds at the same time.)
As you usually can't predict where the next error will happen, probably put all of this in a wrapper script which performs the redirection, runs the build, and finally displays the tail end of the temporary log files. Some build servers probably want to see some signs of life in the log file every few minutes, so perhaps tail a few lines every once in a while in a loop, too.
On the other hand, if there is just a single build command, the whole build job's stdout and stderr can simply be redirected to a log file, and you don't need to exec things back and forth. If you need to enable output selectively for portions of the script, use exec as above; but for wholesale redirection, just redirect the one command.
In summary, maybe your build script would look something like this.
#!/bin/sh
t=$(mktemp -t -d cibuild.XXXXXXXX) || exit
trap 'kill $buildpid; wait $buildpid; tail -n 500 "$t"/*; rm -rf "$t"' 0 1 2 3 5 15
# Your original commands here
${initial_process_wd}/internals/declination/create "${RELEASE_VERSION}" "${CI_COMMIT_REF_NAME}">"$t"/stdout 2>"$t"/stderr &
buildpid=$!
while kill -0 $buildpid; do
sleep 180
date
tail -n 1 "$t"/*
done
wait
A flaw with this approach is that you lose timing information. A proper solution woud let you see when each line was produced, and display standard output and standard error intermixed in the order the messages were printed, perhaps with visible time stamps, and even with coloring hints (red time stamps for stderr?)
Option 1
If your script will output the error message to stderr, you can ignore all output to stdout by using command > /dev/null, where /dev/null is a black hole that will take away any output to it.
Option 2
If there's any pattern on your error message, you can use grep to filter out those error messages.
Edit 1:
To show the command that is running, you can supply -x command to bash; therefore, your command will be
bash -x ${initial_process_wd}/internals/declination/create "${RELEASE_VERSION}" "${CI_COMMIT_REF_NAME}" > /dev/null
bash will print the command executed to stderr
Edit 2:
If you want to reduce the size of the output file, you can pass it to gzip by using ${initial_process_wd}/internals/declination/create "${RELEASE_VERSION}" "${CI_COMMIT_REF_NAME}" | gzip > logfile.
To read the content of the logfile, you can use zcat logfile.

In bash, Loop and send commands to execute

Im trying to execute a program and send it commands based on a file that Im reading but as soon as I send the command the loop stop..it must be related to pipes but I would appreciate if someone could explain how they work
Code:
function setValue{
echo "$1" > &9
}
mkfifo program.fifo
./program
exec 9 > program.fifo
while read value
do
setValue $value
done < file.csv
file.csv has 8000 rows, but the program stops after the first line...and finishes the execution without looping on any more lines of the csv
By leaving the pipe open for reading the loop is not finished after reading the first line and it can continue to the end of the file:
exec 9 <> program.fifo
What is reading from program.fifo? If there is no process that is reading it, then your script is blocked trying to write. That write will not complete until some process is reading the fifo.
My guess is that the code you aren't showing us in the while loop is consuming all of its stdin, which is the same as the input of the while loop. The cleanest way to avoid that is to ensure that the commands in the loop are not reading from the same file as the loop. There are many ways to do that; I like:
while read value; do {
commands
} < /dev/null
done < file.csv

input file start_position => "beginning" doesn't work even after deleting .sincedb files

Version: ElasticSearch-5.2.1/Logstash-5.2.1/Kibana-5.2.1
OS: Windows 2008
I've just started working on the ELK Stack & am facing some problems loading data
I've got the following .json code
input {
file {
path => "D:\server.log"
start_position => beginning
}
}
filter {
grok {
match => ["message","\[%{TIMESTAMP_ISO8601:timestamp}\] %{GREEDYDATA:log_message}"]
}
}
output {
elasticsearch {
hosts => "localhost:9200"
}
}
I've deleted the .sincedb files
And yet when I extract log info in Kibana, I can see data starting only since I first parsed. I've got data worth 2-3 months in my log file.
What if you have your file input as such, where you're missing out the ignore older which actually will stop you re-reading the old files plus you're missing out the since db path property I believe. You could have a look up on this answer by #Steve Shipway for a better explanation on having these two properties within your file input.
So your input could look something like this:
input {
file {
path => "D:\server.log"
start_position => "beginning" <-- you've missed out the quotes here
ignore_older => 0
sincedb_path => "/dev/null"
}
}
Note that setting sincedb_path to /dev/null will make the files read from the beginning, every time which isn't a good solution at all. But then deleting the .sincedb file should work I reckon. If you really want to pick up lines from where you left off, you really need the .sincedb file to hold into the last position which got updated lastly. You could have a look on this for a detailed illustration.
Hope this helps!
in my case, when you enter systemctl restart logstash, even if you have deleted the sincedb file, logstash before the process closes save a new sincedb file and then closes.
if you want really read file from beginning, you should:
stop the logstash service: sudo systemctl stop logstash
delete sincedb file from /var/lib/logstash/plugins/inputs/file or /usr/share/logstash/data/plugins/input/file directory
start the logstash service: sudo systemctl start logstash

Logstash not running

I've a logstash instance, version 2.3.1 which isn't running using the command
sudo service logstash start
Whenever I run this command, it returns logstash started and after a few moments when I check the status, I find that logstash isn't running. Although, when I start the logstash from opt to get output on the terminal, it runs without any error.
Note that logstash.err and logstash.stdout files are empty and logstash.log file isn't anywhere to be found. I've also set LS_GROUP to adm in init.d which caused the same issue on another instance, but even that doesn't seem to work now. Any help would be appreciated!
On an Ubuntu system, this behavior can be seen by logstash. To get around it, you can change the logstash user group in /etc/init.d/logstash to adm which stands for admin and you're good to go.
This is normal behaviour of Logstash.
Can you test if your Logstash instance is working correctly?
Windows:
Go to your bin folder of logstash
and type logstash
Linux:
Enter this command in the prompt (bin folder of your logstash instance)
/opt/logstash/bin/logstash
Both:
If you get No command given ... you're logstash instance has the correct setup.
You can always run your Logstash instance with this command
logstash -e 'input { stdin { } } output { stdout {} }'
After this you can enter some text values and they will output to your console.
If this all works you can be sure that your Logstash instance is running correctly.
You may ask yourself why is this? This is because Logstash waits to start untill it gets a config to run with or another option.
If you want to start Logstash automatically on startup. You need to use this command.
sudo update-rc.d logstash defaults 96 9
Actually,you should read the guide of logstash.In the "getting started section",The official documentation has the corret way for you to start a logstash work.
First,you should write a configure file such as "std.conf",look like this:
input {
stdin {
}
}
output{
stdout{
codec=>rubydebug
}
}
Then,start your logstash:
bin/logstash -f conf/std.conf
If you want this work can run in the background(such as get some log files into elasticsearch),you may also need add "&" in the end of the command,like this:
bin/logstash -f conf/getlog.conf &
with this file(std.conf) and this command,your logstash will start up and if you type any word in you terminal,it will print out in the terminal,like this:
{
"message" => "hello",
"#version" => "1",
"#timestamp" => "2016-08-06T19:47:36.543Z",
"host" => "bag"
}
Now,you have got the normal operation of logstah,you may need more information,from there:The official documentation of logstash
Try this,and keep going,it`s easy for you~

how to install logstash on windows 7

How to install logstash on Windows 7?
I install zip file which size is 90 mb and then version is logstash-1.5.0
and extract then file and move it to the bath C:\Logstash
When I run:
C:\Logstash\logstash-1.5.0\bin\logstash
I have the following message:
io/console not supported; tty will not be manipulated
No command given
Usage: logstash [command args]
Run a command with the --help flag to see the arguments.
For example: logstash agent --help
Available commands:
agent - runs the logstash agent
version - emits version info about this logstash
any help
thank you
The most simple way to get started and verify that your logstash is working is to start it with the following command
logstash -e 'input { stdin { } } output { stdout {} }'
this means that logstash will echo what you type in the console back out to the console, for example:
C:\logstash\bin>logstash -e 'input { stdin { } } output { stdout {} }'
io/console not supported; tty will not be manipulated Settings:
Default filter workers: 4 Logstash startup completed
I typed this
2015-12-11T09:22:22.349Z MY_PC I typed this
and then I typed this
2015-12-11T09:22:26.218Z MY_PC and then I typed this
The next thing to do is read an input from something else, for example your windows logs. For this you can save a config file to your bin folder, it can be called anything, for instance 'logstash.config'. Contents as below
# contents of logstash\bin\logstash.config
input {
eventlog {
type => 'Win32-EventLog'
logfile => 'System'
}
}
output {
stdout { }
}
If you then run
logstash -f logstash.config
Leave this running for a bit and you will see that your windows event log gets written out to the console. (You could trigger some events by running iisreset in a different console.)
not sure why is says "io/console not supported; tty will not be manipulated", probably because it is running in a windows console, but logstash is still working.
Make a conf file and paste it in bin folder of logstash
and type
in cmd logstash/bin>logstash agent -f logstash.conf
You have to run logstash manually by command in windows 7. tc-log.conf is my conf file. lslog.log is my log file. Change directory to the bin folder of logstash and run following command .
*make sure that you have done changes in command as per yours.
logstash agent -f D:/cloud/logstash-1.4.2/tc-log.conf -l D:/cloud/logstash-1.4.2/logs/lslog.log –verbose
I tried this method but using the test command I obtained:
Cannot find Java 1.5 or higher.
I have %LS_HOME%, %JAVA_HOME% and the PATH updated.
Debugging the logstash.bat (with echo) I found error is raised by:
%JRUBY_BIN% "%LS_HOME%\lib\bootstrap\environment.rb" "logstash\runner.rb" %*
%JRUBY_BIN% and "%LS_HOME% are rightly defined:
- "C:\ELK\logstash\vendor\jruby\bin\jruby"
- "C:\ELK\logstash"
Thanks.

Resources