awesomeWM / awesome

awesome window manager
https://awesomewm.org/
GNU General Public License v2.0
6.34k stars 597 forks source link

Getting system information such as: memory, disk space, CPU usage... #589

Closed mindeunix closed 8 years ago

mindeunix commented 8 years ago

I know there are already modules like Vicious or Obvious but their biggest problem is that they need to run other programs in order to get information which makes the system slow or even unstable. Yes, we have already asynchronous I/O functions which somehow improve this procedure, but It would be really great to get this information from awesome, without any external tool. I think this feature can improve many users configurations.

Elv13 commented 8 years ago

Sure, but this is a lot of code to get "right". And by "right", I mean properly non blocking and all. Then there is the fact that Awesome run on 7-8 OSes with totally different interfaces for this. Beside porting Conky to be compatible with GLib event loop and LGI, I don't see how this could happen. That's a lot of code compared to a bunch of non blocking scripts/commands. Vicious design is aging a lot and it could be upgraded to use better async interfaces (without recursive async calls that crash LGI[2]).

Then, my https://github.com/Elv13/lua_async_binding module is slowly getting ready for mainstream usage. It work quite well already and can replace most of the old fs_async.lua [3] module from my config. This module should solve the issues of reading /proc files under I/O load that plague vicious[1]

[1] /proc maybe a virtual file system, but many calls, such as battery life are blocking and only as fast as the scheduler latency + I/O wait latency + hardware ioctl on the battery controller itself. On my old Dell (i3 1.6ghz, 1gb, 4200RPM HDD) I have seen such call benchmarked well over 100ms under load.

[2] LGI async methods work fine, but only has long as they are not calling other async methods. If this happen, LGI memory get corrupted, as proved with Valgrind and test scripts. This is not fixed as the LGI maintainer don't seem very interested in fixing it. This is why I am writing a new C module that avoid using GObject introspection.

[3] Implemented with unit test:

      gears.async.directory.scan
      gears.async.directory.watch
      gears.async.file.read
      gears.async.file.append
      gears.async.file.write
      gears.async.file.info
      gears.async.file.icon
      gears.async.file.thumbnail
      gears.async.icon. load
mindeunix commented 8 years ago

Maybe https://github.com/GNOME/libgtop can help to solve the most coding part?

#include <glibtop.h>
#include <glibtop/mem.h>
#include <glibtop/swap.h>

#include <glib.h>
#include <unistd.h>

static unsigned mb(guint64 n)
{
        return n >> 20;
}

int main(int argc, char **argv)
{
        glibtop_mem mem;
        glibtop_swap swap;

    glibtop_init();

        glibtop_get_mem(&mem);
        glibtop_get_swap(&swap);

        printf("              total        used        free      shared  buff/cache   available\n");
        printf("%-7s %11u %11u %11u %11u %11u %11u\n",
               "Mem:",
                mb(mem.total),
                mb(mem.used - mem.buffer - mem.cached),
                mb(mem.free),
                mb(mem.shared),
                mb(mem.buffer + mem.cached),
                mb(mem.total - mem.user));

        printf("%-7s %11u %11u %11u\n",
               "Swap:",
                mb(swap.total),
                mb(swap.used),
                mb(swap.free));

    glibtop_close();

    return 0;
}
psychon commented 8 years ago

I'd rather not have this in awesome itself. As Elv13 already said: Portability. And the CHANGES files of libgtop mentions too many ABI breakages for my taste. Also, their Github repo contains some daemon...? I don't know anything about it, but requiring some daemon sounds weird to me.

In debian, the libgtop2 source package builds a binary package called gir1.2-gtop-2.0. So apparently this uses GObject and can just be used from lgi without any further change in awesome itself?

mindeunix commented 8 years ago

I just created a pull request if someone want to try how it works #590

mindeunix commented 8 years ago

I do not know anything about ABI breakages... Libgtop is designed to be as portable as possible.

About daemon: The LibGTop @dfn{server} is a setgid/setuid binary which contains all the system dependent code which needs special privileges. It is only build if it's required on the current system (for instance, the Linux kernel provides all the required data via its @file{/proc} filesystem so we do not need the server at all) and it only contains the @dfn{features} which need privileges. Whenever we do not need any privileges to get all the data for some of the requested structures (here called @dfn{features}) the library calls the sysdeps code directly rather than using the server.

If you really not interested then please close this issue. I at least tried, so thank you anyway.

blueyed commented 8 years ago

I agree with @psychon that it might be better to use lgi instead.

@mindeunix Have you tried using it through this?

mindeunix commented 8 years ago

@blueyed Yes, of course I tried (and as far as I remember it did not work).

I just wrote this issue because its a great feature to have, but now I see that it only interested me. From my side it's not a big deal, I will find my own way.

blueyed commented 8 years ago

It would be nice to have, of course - but then through the lgi bindings, which seem to be easier to maintain. Maybe you want to give this another try?

psychon commented 8 years ago

I tried using libgtop2 through lgi. I quickly gave up. I don't know what is up, but lgi throws lots of errors. Apparently the annotation information is nothing that it likes.

For the PR: I don't know how useful it is to try to write our own libgtop lua bindings. There will always be something missing that someone wants added. This has a high chance of being a never ending story of feature requests.

Edit: https://github.com/pavouk/lgi/pull/126 makes lgi not error out when loading GTop's introspection functions.

psychon commented 8 years ago

Oh and here is some example on how to call GTop via LGI:

$ lua -e 'g = require("lgi").GTop ; cpu = g.glibtop_cpu() ; g.glibtop_get_cpu(cpu) ; print(cpu.flags, cpu.frequency, cpu.total,cpu.user,cpu.nice,cpu.sys,cpu.idle)' 
260095.0    100.0   12875847.0  139375.0    4405.0  24635.0 12692109.0

@mindeunix Does something like this help you? It has the nice appeal of not having to write lua bindings for GTop (and update them when something in GTop changes)

psychon commented 8 years ago

And here is a port to Lua of the C code from https://github.com/awesomeWM/awesome/issues/589#issuecomment-162808919:

GTop = require("lgi").GTop
GTop.glibtop_init()

mem = GTop.glibtop_mem()
swap = GTop.glibtop_swap()
GTop.glibtop_get_mem(mem)
GTop.glibtop_get_swap(swap)

function mb(i)
    return i / (2^20)
end

print("Total:", mb(mem.total), "Used:", mb(mem.used - mem.buffer - mem.cached), "Free:", mb(mem.free), "Shared:", mb(mem.shared), "Buff/Cache:", mb(mem.buffer + mem.cached), "Available", mb(mem.total - mem.user))
print("Swap:", mb(swap.total), mb(swap.used), mb(swap.free))

GTop.glibtop_close()

Output (Sorry, I skipped the nice output format):

Total:  32049.1796875   Used:   1120.94921875   Free:   20491.29296875  Shared: 438.6328125 Buff/Cache: 10436.9375  Available   30330.00390625
Swap:   16071.99609375  0.0 16071.99609375

(This only works with https://github.com/pavouk/lgi/pull/126)

mindeunix commented 8 years ago

@psychon Thanks, these changes removes from my configuration more than a 1000 lines of code, so it's definitely good improvement.

psychon commented 8 years ago

@blueyed Do we want to "invade" the space of the many widget libraries and make GTop an optional dependency of awesome? I still don't think we can make everyone happy (there will always be some missing feature => we get many feature requests => this can result in lots of code being shoved into awesome), so this feels dangerous to me. At least this a lot better than writing our own Lua bindings for GTop :-)

actionless commented 8 years ago

while lgi-based solution not requires any changes on awesome side, why those widgets can't live just in a separate repo?

mindeunix commented 8 years ago

@actionless maybe it would be easier for newcomers to start writing their own widgets? They will get along with the Awesome all the "instruments" that can ever be needed without digging through internet what to choose, how to use...

psychon commented 8 years ago

Well, why do we have menubar, awful etc in awesome? People could write their own version. ;-)

I could write something that checks if GTop is available and then either creates empty widgets or widgets with actual content (memory usage etc). That way nothing changes for people who do not have GTop, but distros will likely add something like a "Recommends" to the awesome package and so newcomers would get the widgets.

Should I "invade conky's use case" and do this as something that is on the desktop? :-)

Elv13 commented 8 years ago

Well, in 3.4, I ported my Conky config to Awesome capi.image.draw (RIP). Beside slowing by desktop down, it didn't really had any benefits, I later switched back.

I guess it all come down to performance. Are any of those calls blocking or slow? I haven't checked, so I don't know. Maybe Awesome could be made to avoid painting/updating such desktop widget when it is fully hidden?

Other than that, yes, I do think it would be better to guide the users into something reliable and fast. The wiki isn't a nice land for newcomers. Half of the widgets are for 3.4, or broken, or worst.