Linux下时间记录工具(arbtt/ulogme,类ManicTime)

tl;dr

Linux下程序运行状态记录软件建议使用ulogme,而不是arbtt!!!
目录

  1. 文章起源
  2. arbtt介绍
  3. ulogme介绍
  4. uLogMe 新一代产品介绍

1. 起源

切换到Linux环境下最头疼的一个事就是缺少了ManicTime类似的办公工具,用于记录每天打开各个程序和文档的时间,文档和程序的标题,以便在日后可以回顾当天做了什么。
当然,有很多类似的手工记录工具,开始做一件事情之前通过软件记录一个时间点和内容,随后再检索,但是太麻烦了,需要频繁的人工参与操作。
之前在Windows上用的最舒服的一个软件就是ManicTime,即便是免费版本也可以很好的胜任工作,可以检索出每天都做了什么,操作了什么文档(这个非常非常关键!!!也是我一直需要的功能,可以检索出当天参与了什么项目)。可惜它只有Windows和Mac版本,没有Linux版本。ManicTime软件截图(Baidu找了一个图,现在已经没有Windows系统了):


ManicTime截图(from 百度)

切换到Ubuntu后,通过alternativeto.net找到了RescueTime软件,类似于ManicTime的自动记录软件,RecueTime是一个Native app+Remote WebUI结合的系统,数据通过本地Native app收集,并传递到RescueTime网站(稍微有点不安全,会泄露一些信息),通过在网站的WebUI上展现数据实现信息的展示,功能非常全面,界面如下:


RescueTime WebUI截图

截图Ubuntu顶部标题栏的白色十字图标即是RescueTime的Native app。

但是RescueTime免费版只能看到每天打开的程序信息,收费版才能看到详细的文档名字,我的核心功能需求(回溯每天参与的项目)没有被满足!!!

随后又通过alternativeto.net找到了arbtt,一个开源的自动记录软件,看了网站上的一些demo,完全本地运行,相对RescueTime安全很多。而且可以看到打开的文件(核心需求啊!!!),随后开始研究这个东西。

2. arbtt介绍

arbtt官网

arbtt由多个组件组成:

  1. arbtt-capture,负责收集打开的程序和文档标题,并记录在一个日志文件中
  2. arbtt-stats,负责读取arbtt-capture记录的日志文件,并通过指定的过滤规则(配置文件或命令行直接输入参数)显示出用户定制的内容

通过arbtt-capture和arbtt-stats的有机组合可以实现灵活的日常操作工作的显示。

2.1 arbtt安装

arbtt已经集成到ubuntu的官方仓库,可以直接apt-get安装。
参考URL:http://arbtt.nomeata.de/#install

  1. 安装软件
sudo apt-get install arbtt
  1. 配置程序开机自启动
    cp /usr/share/doc/arbtt/examples/arbtt-capture.desktop ~/.config/autostart/

  2. 立即启动程序
    arbtt-capture &

  3. 让arbtt-capture收集一会信息

  4. 启动arbtt-stats查看收集的信息
    给arbtt-stats一个基本的配置,让其正常启动工作:

echo "{\\$idle > 60 ==> tag inactive}" > ~/.arbtt/categorize.cfg

通过arbtt-stats查看收集的信息:

ray@ray-ThinkPad-X250:~/Applications/arbtt-graph/render$ arbtt-stats 
Total time per tag                                                                                                                              
==================
__________________________Tag_|______Time_|_Percentage_
                     Desktop: | 10h24m00s |     100.00
        Program:google-chrome |  4h16m00s |      41.03
Program:gnome-terminal-server |  3h17m00s |      31.57
                   Program:et |  2h10m00s |      20.83

2.2 arbtt-stats使用

arbtt-capture只负责数据收集,并不能展示数据,数据展示的方法是读取arbtt-capture收集的log文件,官方提供的工具是一个CLI工具,arbtt-stats。

arbtt-stats需要一个配置文件才能正常工作,这个配置文件指定了一些过滤和显示规则,告诉arbtt-stats显示哪些log文件的数据。

2.3 arbtt-graph

arbtt-graph项目主页:https://github.com/rejuvyesh/arbtt-graph

arbtt-graph与arbtt-stats功能一样,都是用于展现arbtt-capture的数据,不同的是arbtt-stats是CLI显示,arbtt-graph是WebUI。

arbtt-graph功能较arbtt-stats弱一些,不能操作多个category,导致不能多维度显示(程序和标题)。

arbtt-graph WebUI截图

arbtt-graph安装完成后需要修改如下几部分,以使其正常工作:

  1. arbtt-graph/update文件
    官方文件要求修改此文件,实际上只需要确保该文件下如下两个字段没问题即可,一般都是正常的,不用修改:
CATEGORIZE_FILE="./categorize.cfg"      <----与arbtt-stats一样,需要指定配置文件位置
CATEGORY="Graph"    <----指定arbtt-graph显示那个Category到WebUI,只显示在此配置的Category

修改后需要执行一下这个文件,./update文件可以直接执行。

  1. arbtt-graph/categorize.cfg文件
    arbtt-graph的配置文件(过滤规则),用于指明WebUI显示的内容,作用范围除了Barcode view外的所有内容。
    Paste_Image.png

    将需要通过WebUI显示的Tag分配到上述update文件指定的Category下,如默认的是Graph,我的配置如下,与arbtt-stats文件的规则和内容可以完全一样:
ray@ray-ThinkPad-X250:~/Applications/arbtt-graph$ cat categorize.cfg 
-- -*- mode: haskell; -*-
$idle > 60 ==> tag inactive,
current window $program == ["gnome-terminal-server"]  ==> tag Graph:term,
current window $program == "et"  ==> tag Graph:office,
current window $program == "wpp"  ==> tag Graph:office,
current window $program == "wps"  ==> tag Graph:office,
current window $program == ["Navigator", "chromium", "google-chrome"] && !(current window $title =~ [m!YouTube!, m!Vimeo!, m!Facebook!, m!Google+!, m!Twitter!, /.*Hacker News.*/, /.*Less Wrong.*/, /.*[Rr]eddit.*/, /.*Goodreads.*/, /.*GitHub.*/, /.*Ask.fm.*/, /.*Ino[Rr]eader.*/, /.*Gmail.*/, /.*New\\ Tab.*/]) ==> tag Graph:browsing,
current window $title =~ [/.*irssi.*/, /.*WeChat.*/] ==> tag Graph:irc,
current window $title =~ /.*pdf.*/ ==> tag Graph:read-pdf,
current window $title =~ /.*djvu.*/ ==> tag Graph:read-djvu,
current window $title =~ /.*epub.*/ ==> tag Graph:read-epub,
current window $title =~ /.*mobi.*/ ==> tag Graph:read-mobi,
current window $title =~ /.*azw3.*/ ==> tag Graph:read-azw3,
current window $title =~ /.*Spreadsheets.*/ ==> tag Graph:office,
current window $title =~ /.*Writer.*/ ==> tag Graph:office,
current window $title =~ [m!mp4!, m!mkv!, m!avi!] ==> tag Graph:tv-local,
tag Graph:$current.program,
  1. arbtt-graph/render/settings.js文件
    用于指定哪些Tag显示到Barcode上,Barcode就是arbtt-graph主页面最下边的长条图:


    Barcode view

    我的配置如下:

ray@ray-ThinkPad-X250:~/Applications/arbtt-graph/render$ cat settings.js
// Barcode view settings
var display_groups = [];
display_groups.push(["social", "misc", "browsing", "office", "term"]);
  1. 修正arbtt-graph/render/overview/overview.html页面显示问题,默认该页面因为变量配置错误,导致图示的x轴太短,看不到(并不是没有数据!!!)。


    错误页面,并通过chrome调试页面查看报错

    需要对该文件如下部分的变量进行修改:

      function drawData() {
        $("#content").empty();
        // draw the legend on top of the svg
        var d3div = d3.select("#content");
        var ldiv = d3div.append("div").attr('class', 'legenddiv');

        for(var i=0; i<tags.length; i++) {
          var pi = ldiv.append('p').text(tags[i]).attr('style', 'color:' + colors[tags[i]]);

          var m = tags[i];
          if(skipdraw[m]) { pi.attr('class', 'skipdrawyes'); }
          else { pi.attr('class', 'skipdrawno'); }
          
          pi.on('click', function(i) { // close over index i
            return function() {
              // toggle whether this one gets drawn
              var m = tags[i];
              if(skipdraw[m] === false) { skipdraw[m] = true; }
              else { skipdraw[m] = false; }
              drawData(); // and redraw the graph!
            }
          }(i));
        }

        var margin = {top: 10, right:10, bottom: 100, left: 40};

        //var fullwidth = 30;
        //console.log(loglist.length * 15)
        var fullwidth = loglist.length * 150;     <----------修改行
        var fullheight = 800;
        var width = fullwidth - margin.left - margin.right;
        var height = fullheight - margin.top - margin.bottom;

其中var fullwidth = loglist.length * 150;为修改后的内容,原值为var fullwidth = loglist.length * 15;,太小了,导致下边的代码调用结果为负值,进而报错,显示失败。

这个arbtt-graph的参考系统是ulogme,几乎代码就是copy过来的,改了少许,可以在Github上看一下源系统的相应代码:
ulogme对应代码:

      var margin = {top: 10, right: 10, bottom: 100, left: 40};
      var fullwidth = 1200;
      var fullheight = 800;
      var width = fullwidth - margin.left - margin.right;
      var height = fullheight - margin.top - margin.bottom;

3. ulogme介绍和使用

URL:https://github.com/karpathy/ulogme
arbtt和arbtt-graph的默认合作模式只展示程序的打开状况,记录每个程序的运行时间和频率,但这并不是我的使用初衷,虽然可以通过调整category.cfg文件变相实现文档打开情况的展示,但是毕竟这不是该软件的设计初衷,所以实现起来也挺别扭。自己修改Javascript太耗费精力,所以有了arbtt-graph的参考系统ulogme的使用介绍。

ulogme是类似于arbtt的开源软件,该软件集成了arbtt-capture和arbtt-graph的功能,原生提供WebUI用于展示。
与arbtt不同的是,ulogme使用的是wmctrl工具包,更多的是截获打开的程序标题,进而处理获取文档及应用程序打开情况。

3.1 ulogme相对于arbtt的优势

  • 提供了原生的文档名称记录,更可贵的是与程序名称关联在一起,即满足了文档名称查看的要求,也不影响页面的观感。
  • 提供了更多的功能:
    • 按键记录(我本人并不使用)
    • 笔记记录(非常有用的功能,可以针对当天进行记录,也可以针对某个时间点的开启程序进行记录,非常方便。

3.2 安装

  1. 获取软件源码
    $ git clone https://github.com/karpathy/ulogme.git
  2. 安装依赖包
    $ sudo apt-get install xdotool wmctrl
  3. 构建配置文件
    $ cp render/render_settings_example.js render/render_settings.js
    修改配置文件
  4. 运行监控截取程序
    $ ./ulogme.sh
  5. 运行WebUI Server
    $ python ulogme_serve.py
  6. 通过浏览器打开ulogme WebUI界面
    http://localhost:8124

3.3 配置优化

  1. ulogme系统分析
    ulogme系统要比arbtt复杂, 除了开启程序和文档的记录外,它还实现了按键频率的统计,用于更深入的实现程序的跟踪记录。但是这个功能我本人并不感冒,而且记录按键部分的script(单独的scirpt)在监控功能启动时还需要root权限,不安全且不方便制作开机启动脚本,所以我就修改跳过了这个功能。
    两个脚本名称:keyfreq.sh(按键监控)logactivewin.sh(程序标题监控)

  2. 开机启动配置
    通过上一节的介绍,我们知道了ulogme包含按键监控程序标题监控两个部分,因为我不需要按键监控的功能,且按键监控启动需要root权限,为了方便设置开机启动,我的开机启动脚本就直接调用 logactivewin.sh(程序标题监控)了。
    在 ~/.config/autostart/目录下建立ulogme.desktop文件:

ray@ray-ThinkPad-X250:~/.config/autostart$ ls
arbtt-capture.desktop  rescuetime.desktop  ulogme.desktop
ray@ray-ThinkPad-X250:~/.config/autostart$ cat ulogme.desktop 
[Desktop Entry]
Encoding=UTF-8
Name=ulogme Data Capture Program
#Icon=
Comment=Records information about the user application usage
Type=Application
#Categories=
Exec=sh -c "cd /home/ray/Applications/ulogme && ./logactivewin.sh"
Terminal=false
StartupNotify=false
ray@ray-ThinkPad-X250:~/.config/autostart$ 
  1. 为Portal页面(python脚本)建立ulogme8124.desktop文件(8124是端口号,打开的时候可以作为提醒),需要注销系统以便生效。
ray@ray-ThinkPad-X250:~/.local/share/applications$ cat ulogmePortal.desktop 
#!/usr/bin/env xdg-open
[Desktop Entry]
Type=Application
Name=ulogme8124
Exec=sh -c "cd /home/ray/Applications/ulogme && python ./ulogme_serve.py"
  1. HTML页面优化
    这个部分主要是对WebUI的定制和修改,同时删掉了按键记录的展示部分,代码涉及比较多,就不展示了。

3.4 页面截图

ulogme Single-day View
ulogme View

ulogme作者的关于量化工作效率的文章:Quantifying Productivity

4. uLogMe (next generation of Ulogme)

URL:https://github.com/Naereen/uLogMe
The project currently only works on Ubuntu or Debian-like Linux (for an OSX version, see the original project). It uses the new fancy Promises
feature of ECMAScript 6. This might not be implemented in all browsers, but recent one should have it (recent Chrome and Firefox are fine, at least).


优势

  1. 更好的UI和性能
  2. 启动脚本本身更完整,可以跨目录直接调用,直接调用做开机自启动,相关脚本目录:
  • scripts/ulogme_data.sh 数据记录功能启动脚本。可以单独直接启动,运行所有窗口名按键记录功能。开机记录功能需要将此脚本加入启动项
  • scripts/ulogme_serve.sh 数据展示功能记录脚本,脚本内配置WEB服务的IP地址、端口号(默认8443端口)等信息。可以单独直接启动,运行UI Web展示服务器功能。即使的查看WEB UI需要为此脚本建立.desktop文件
  • ulogme_tmux.sh 集合启动脚本,仅支持在tmux环境下运行。自动运行上述两个脚本,并独立的窗口双屏显示上述两个脚本运行的结果。
  1. 依旧需要自己建立.desktop文件,需要注销系统以生效。
ray@ray-ThinkPad-X250:~/.local/share/applications$ cat ulogmePortal.desktop 
#!/usr/bin/env xdg-open
[Desktop Entry]
Type=Application
Name=ulogme8443
Exec=/home/ray/Applications/ulogme2/scripts/ulogme_serve.sh
  1. 代码备份和升级

只需要备份render/js/render/js/render_settings.js文件即可,该文件记录UI中应用分类的对应关系。
在备份上述文件的基础上,可以随时git同步官方的代码更新,不能更好!!!

自动调用浏览器查看WEB UI
scripts/ulogme_serve.sh 中包含了调用浏览器的脚本命令,让操作更方便。但默认是调用的firefox,修改其使用chrome,这个是对原代码的第1个修改:

修改默认的浏览器,并设置自动打开

调整PiaChart显示大小
修改index.html

            series: [{
                name: "Work balance",
                data: groupsData,
                size: "30%",  // ray original: 45%
                innerSize: "70%",
                dataLabels: {
                    formatter: function () {
                        return this.y >= 0 ? this.point.name.toUpperCase() + "<br>" + strTimeDelta(this.y, false)
                        + ( this.percentage.toFixed(0) >= 2 ? "<br>(<i>" + this.percentage.toFixed(0) + "%</i>)" : "" )
                        : null;
                    },
                    color: "#000000",
                    style: {
                        fontSize: "11pt",
                    },
//ray delete this line. for showing peripheral line for inner text.     Original: distance: -35,
                    rotation: 0,
                },
                allowPointSelect: true, // ray original: false
                showInLegend: true,  // ray original: false
                animation: animate ? {
                    duration: 400,
                } : false,
            }, {
                name: "Activities",
                data: activitiesData,
                size: "90%",    //ray original: 78%
                innerSize: "70%",
                dataLabels: {
                    formatter: function () {
                        // display only if larger than 1
                        return this.y > 1 ? "<b>" + this.point.name + "</b>: " +  strTimeDelta(this.y, false)
                          + ( this.percentage.toFixed(0) >= 2 ? "<br>(<i>" + this.percentage.toFixed(0) + "%</i>)" : "" )
                          : null;
                    },
                    style: {
                        fontSize: "12pt",
                    },
                },
                animation: animate ? {
                    duration: 600,
                } : false,
            }]
        };

安装步骤
$ git clone https://github.com/Naereen/uLogMe.git
$ sudo apt-get install xdotool xinput wmctrl xprintidle
$ sudo apt install tmux //uLogMe提供的默认的启动脚本就是适用的tmux,确实比较方便,所以直接安装上吧,节省时间
$ cp render/js/render_settings_example.js render/js/render_settings.js
$ mkdir render/json/
$ touch /var/log/pm-suspend.log
$ python export_events.py
$ ./ulogme_tmux.sh //运行后的界面如下:

tmux界面

uLogMe 主界面

自启动
非常简单,直接加入系统启动项即可:

Paste_Image.png

或者在 ~/.config/autostart/目录下建立ulogme.desktop文件,自己写启动脚本,上一章节有介绍。

文件及目录介绍

ray@ray-ThinkPad-X250:~/Applications/ulogme2$ ls -al
total 44
drwxr-xr-x  6 ray ray  4096 Dec  6 13:16 .
drwxrwxr-x 11 ray ray  4096 Dec  6 13:06 ..
-rw-r--r--  1 ray ray  1118 Dec  6 13:03 LICENSE
drwxr-xr-x  2 ray ray  4096 Dec  6 13:20 logs
-rw-r--r--  1 ray ray 15066 Dec  6 13:03 README.md
drwxr-xr-x  6 ray ray  4096 Dec  6 13:29 render
drwxr-xr-x  2 ray ray  4096 Dec  6 13:03 screenshots
drwxr-xr-x  4 ray ray  4096 Dec  6 13:18 scripts
  • logs目录是uLogMe程序记录的所有裸数据。
  • scripts目录是uLogMe python主程序
  • render目录下为WEB UI渲染组建。
    • 目录下的index.html和render/js/下的各类脚本文件实现对页面的显示和对logs目录下的裸数据进行挖掘
    • 上述js脚本将挖掘的结果保存到render/json/下,形成结构化数据.json文件
    • index.html文件中的js相关函数调用结构化数据.json文件,实现数据的展示
    • render/js/render_settings.js //主要负责UI的展示配置,指明如何对应用分类和显示,修改此文件后刷新页面即看到效果。
      • title-mappings变量指定窗口名称和用户自定义名称的映射


        Paste_Image.png
      • mapwin函数由index.html中的js函数进行调用,实现对上述title-mappings变量规则进行应用


        Paste_Image.png
      • display_group 负责对UI 页面中barcode进行配置,说明哪些自定义名称显示在barcode,以及如何分组显示


        display_group代码

        BarCode
      • activity_groups是UI界面上圆形PieChart,分为内、外环。内环是大类,外环是小类。小类是所有在title-mappings配置映射的自定义名称(不是只在activity_groups中配置的),大类是在这个activity_groups中指定的小类进行统计的结果。


        Paste_Image.png

        piechart

后记:使用Chrome查看js变量值,通过chrome console显示

chrome有一个非常好的调试工具集,可以用于调试此次overview页面的问题,通过工具定位故障点,并增加如下参数打印故障节点变量值:

Javascript console.log命令
变量跟踪及故障点定位结果

其他类似的Linux软件

  1. Selfspy
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269

推荐阅读更多精彩内容