View metrics or more insights on HTTP::Server - crystal-lang

We're running a production system on Crystal/Kemal. The calling service sees quite often a Connection refused error. I was wondering how can I see more insights/metrics into a running instance of HTTP::Server/Kemal. I'm referring to the number of fibers running/waiting (out of the maximum number allowed), how large is the backlog of connections, how many have been refused and so on.

Built-in tools: crystal tool -h
context show context for given location
expand show macro expansion for given location
format format project, directories and/or files
hierarchy show type hierarchy
implementations show implementations for given call in location
types show type of main variables
Common tools:
lsof +p $(pidof <process_name>) — display connections/socket for process.
ss -ier — display internal socket stats.
strace -p $(pidof <process_name>) -s 300 -yyfq — useful tool for process introspection.
tcpdump & wireshark — dump and explore network packets
ngrep — like grep but for network packets.
LLDB — native debugger for LLVM-based app (tutorial)
CodeLLDB — Native VSCode debugger based on LLDB.
And don't forget crystal build ./app.cr --debug

Related

Starting the default terminal on Linux

Tell me, please, is it possible to call the Linux Terminal, which is installed by default, in some way (method)?
Now, I run the process in the xfce4-terminal terminal, specifying this terminal and the arguments to it:
QProcess up;
QString cArg;
cArg="/tmp/cp.py -y " + ye;
up.start("xfce4-terminal", QStringList()<< "--geometry=120x40" << "--command" << "python3 "+ cArg << "-H");
up.waitForFinished();
up.close();
No, there is no general way in the Linux kernel to find out which (or whether a) terminal emulator is installed on the system by default.
Although the (fairly ubiquitous) freedesktop.org specifications describe how to associate MIME type with a default application, there isn't a specification for default application without an associated file to be opened as far as I can tell. Each desktop environment that has a concept of "default terminal emulator" has their own way of configuring it.
Debian has has "update-alternatives" system that allows configuration of "default" applications based on aliases, and it has a package that creates an alias x-terminal-emulator that can be used to configure the default terminal emulator.
Here is a reasonable strategy for choosing the command in your program:
Let the user configure the command. Use this with highest priority if configured.
Use XDG_CURRENT_DESKTOP environment variable, and implement logic for each desktop environment to read their configuration to find out the configured default emulator. Use this as the second highest priority when available.
Collect a list of commonly used terminal emulators. Put aliases such as x-terminal-emulator with higher priority in the list.
With this list starting with user configuration and ending with your hard-coded list, check each command and see if it's executable and pick the first one that is. In case user has configured the command, and it isn't executable, I recommend an optional error message.
You can use i3's sensible-terminal script.
https://github.com/i3/i3/blob/next/i3-sensible-terminal
While it has been made for i3, if you read the source you'll see it's very simple and doesn't rely on it, so feel free to use this within whatever desktop environment you want.
Though if you don't use i3 you may want to remove the last line (which isn't that important as you are unlikely to have no terminal installed at all).
Explanations
It proceeds by getting, in this order:
A terminal you may have defined in the non-standard $TERMINAL environment variable
x-terminal-emulator which is a similar utility for Debian only
A list of hardcoded terminals, namely mate-terminal gnome-terminal terminator xfce4-terminal urxvt rxvt termit Eterm aterm uxterm xterm roxterm termite lxterminal terminology st qterminal lilyterm tilix terminix konsole kitty guake tilda alacritty hyper

Problems configuring <on-connect> in icecast.xml

I have defined the following mountpoint in the icecast.xml project:
<mount type="normal">
<mount-name>/data.ogg</mount-name>
.....
<on-connect>sh /bin/stream-start.sh</on-connect>
</mount>
And defined a stream.sh script in /bin/stream-start.sh.
It is supposed that when http://..../data.ogg request is executed the stream-start.sh must be executed but is not executed. I have now the following questions:
How must the on-connect script be defined (/bin/stream-start or /bin/stream-start.sh)
how can you pass parameters to the starting script.
In general you'll find it helpful to examine the Icecast logs. Both access.log and error.log may contain important information. Also it might be helpful to adjust loglevel up and restart Icecast for it to take effect.
https://icecast.org/docs/icecast-2.4.1/config-file.html#log
on-connect
State a program that is run when the source is started. It is passed a parameter which is the name of the mountpoint that is starting. The processing of the stream does not wait for the script to end.
Caution should be exercised as there is a small chance of stream file descriptors being mixed up with script file descriptors, if the FD numbers go above 1024. This will be further addressed in the next Icecast release.
This option is not available on Win32
(emphasis mine)
https://icecast.org/docs/icecast-2.4.1/config-file.html#mountsettings
Please also note that you can not rely on 'the usual' environment variables of an interactive shell being present, as e.g. PATH will not be populated. You might want to just export >/tmp/on-connect-env.txt from within the script and examine its contents to get an idea what you'll work with. Also you can not pass the interpreter as part of the command like you did above, you must put the interpreter with its full path in the shebang (#!) on the first line of the script.

Get details of Linux kernel modules in C++

In Linux, I need to get the details(viz. service exit code,status,type,etc) of all the driver modules and I tried reading /proc/modules. But it gives only name, size and use count. I read that modinfo retrieves info from lib/modules/,but all modules doesn't have all info in it. From where can I get these details reliably. I am coding in C++.
Kernel modules are handled by struct module. You may write a module to get that information from in-kernel (and provide it in another /proc file) or use a debugger to read raw kernel memory from /proc/kcore .
But, the information Linux keeps per-module doesn't fit your needs:
service exit code is not saved by kernel but immediately returned to init_module() caller as error number (i.e. modprobe or insmod tools)
status -- there is no such thing. Closest is state, but it transitional and only used during loading
type -- Linux doesn't distinguish module types
Generally speaking, you cannot get that details from Linux. The most useful information is already provided in /proc/modules.

Extract execution log from gdb record in a VirtualBox VM

I am attempting to use gdb's record feature to generate a list of the instructions executed for the tutorial example
I can use gdb record to step forward and back successfully and save the execution log to a file using "record save".
I think what I want to do is "record instruction-history" which from docs
Disassembles instructions from the recorded execution log
But when I attempt this i get the error:
You can't do that when your target is 'record-full'
Attempting to set the record target to btrace returns the error:
Target does not support branch tracing.
I am running gdb 7.6 in a VirtualBox VM, do i need to be running natively or is there some other magic i'm missing.
Your problem comes from a problem on VirtualBox itself to perform this operation. As you can see in this link, more specifically in this lines:
if (packet->support != PACKET_ENABLE)
error (_("Target does not support branch tracing."));
This problem is explained here.
But VirtualBox does NOT
emulate certain debugging features of modern x86 CPUs like branch target
store or performance counters.
My best guess is to install some other VirtualBox features that allow you to perform such operations, or switch to a new virtual environment.
I'll keep searching for information.

How to use lsof(List Opened Files) in a C/C++ application?

Is there any way to get all opened sockets using c++? I know the lsof command and this is what I'm looking for, but how to use it in a c++ application?
The idea is to get the FD of an opened socket by its port number and the pid.
Just open the files in /proc/net, like /proc/net/tcp, /proc/net/udp, etc. No need to slog through the lsof sources. :)
If you don't want to copy/paste or reimplement chunks of the lsof code, and it doesn't build any useful libraries you could leverage, you can still open a pipe to an lsof process and peruse its output.
check the lsof source?
ftp://lsof.itap.purdue.edu/pub/tools/unix/lsof/
The lsof command is prepared specifically such that it can be used from other programs including C, see the section: OUTPUT FOR OTHER PROGRAMS of man lsof for more information. For example you can invoke lsof with -F p and it will output the pid of the processes prefixed with 'p':
$ lsof -F p /some/file
p1234
p4321
you can then use popen to execute this commmand in a child process and read from its standard output.
In C (or C++) you can use the NETLINK_SOCK_DIAG interface. This is a socket that gives you access to all that information. You can filter on various parameters such as the interface the socket is attached to.
The documentation is spares, however, but I wrote a low level test to see whether I could get events whenever someone opened a new socket, but that didn't work. That being said, to list existing sockets, you can use the following code as a good starting point:
Can the NETLINK/SOCK_DIAG interface be used to listen for `listen()` and `close()` events of said socket?
I think that this is cleaner than parsing the /proc/net/tcp and other similar files. You get the same information, but it comes to you in binary.
It may also be simpler to use the libnml library which is a layer over the socket. It does many additional verification on all the calls. However, just like the base NETLINK interface, it's not very well documented (i.e. whether binding is important, flags you can use with TCP or UDP, etc.) The good thing is: you can always read the source to better understand what's going on.