                         ----------------------
                            Tuptime    Manual
                         ----------------------
                              version 3.3.0
                                Ricardo F.
                              28/March/2016



============
| Abstract |
============

Tuptime report historical and statistical running time of the system, keeping it between restarts.
Indeed, it can:

  - Count system startups
  - Register first boot time (a.k.a. installation time)
  - Count nicely and accidentally shutdowns 
  - Uptime and downtime percentage since first boot time
  - Accumulated system uptime, downtime and total
  - Largest, shortest and average uptime and downtime
  - Current uptime
  - Print formatted table or list with most of the previous values
  - Register used kernels
  - Narrow reports since and/or until a given startup or timestamp
  - Reports in csv



=================
| Prerequisites |
=================

Operating system:
   - Linux
   - FreeBSD
   - OSX (Darwin)

Software:
   - Python 2.7 or Python 3.X (Latest recomended)
   - Python modules (most included in python core by default):
       sys, os, optparse, sqlite3, datetime, locale, platform, subprocess, logging, time

If a distro is used, all is met with:
    - In Linux:  'python' package >= 2.7
    - In FreeBSD: '/usr/ports/lang/python' and '/usr/ports/databases/py-sqlite3'
    - In OSX: 'python' installed by default in base system



================
| Installation |
================

For Linux systems:

   + Package install .deb

      Available in Debian Sid (unstable):

         https://packages.debian.org/sid/tuptime

   + Using .sh script:
      
      Download and execute the installation script:

         # bash <(curl -s https://raw.githubusercontent.com/rfrail3/tuptime/master/tuptime-install.sh)

   + Manual install

      Clone repository and copy executable file:

         # cp tuptime/src/tuptime /usr/bin/tuptime
         # chmod 755 /usr/bin/tuptime 

      Add tuptime user:

         # adduser --quiet --system --no-create-home --group \
                --home "/var/lib/tuptime" \
                --shell '/bin/sh' \
                --gecos 'Tuptime execution user,,,' tuptime

      Execute tuptime with a privilege user for create db path:

         # tuptime

      Change owner of the db file:

         # chown -R tuptime:tuptime /var/lib/tuptime

      Copy cron file:

         # cp tuptime/src/cron.d/tuptime /etc/cron.d/tuptime
         # chmod 644 /etc/cron.d/tuptime

      If is a system with systemd, copy service file and enable it:
	
         # cp tuptime/src/systemd/tuptime.service /lib/systemd/system/
         # chmod 644 /lib/systemd/system/tuptime.service
         # systemctl enable tuptime.service

      If have upstart system, copy the file:

         # cp tuptime/src/init.d/redhat/tuptime /etc/init.d/tuptime
	 # chmod 755 /etc/init.d/tuptime
	 # chkconfig --add tuptime
	 # chkconfig tuptime on

      If have init system, copy the file:

         # cp tuptime/src/init.d/debian/tuptime /etc/init.d/tuptime
         # chmod 755 /etc/init.d/tuptime
         # update-rc.d tuptime defaults
	 # /etc/init.d/tuptime start


For FreeBSD system:

   + Using FreeBSD ports

     Located at /usr/ports/sysutils/tuptime

   + Manual install

      Clone repository and copy executable file:

         # cp tuptime/src/tuptime /usr/local/bin/tuptime
         # chmod 755 /usr/local/bin/tuptime 

      Add tuptime user:

         # pw adduser tuptime -d /nonexistent -s /bin/sh -c "Tuptime execution user"

      Execute tuptime with a privilege user for create db path:

         # tuptime

      Change owner of the db file:

         # chown -R tuptime:tuptime /var/lib/tuptime

      Add an entry to /etc/crontab

         */5     *       *       *       *       tuptime    /usr/local/bin/tuptime -x

      Copy rc.d file:

         # cp tuptime/src/rc.d/freebsd/tuptime /usr/local/etc/rc.d/tuptime
         # chmod 555 /usr/local/etc/rc.d/tuptime
         # echo 'tuptime_enable="YES"' >> /etc/rc.conf


For OSX system:

   Tuptime is compatible with OSX but, for now, the project lacks of launchd files
   for the startup and the schedule run.



============================
| Command line  parameters |
============================

These are the command line options, no configuration file is used:

  -h, --help            show this help message and exit
  -c, --ckernel         classify / order by kernel
  --csv                 csv output
  -d DATE_FORMAT, --date=DATE_FORMAT
                        date format output
  -e, --end             order by end state
  -f FILE, --filedb=FILE
                        database file
  -g, --graceful        register a gracefully shutdown
  -k, --kernel          print kernel information
  -l, --list            enumerate system life as list
  -n, --noup            avoid update values
  -o, --offtime         order by offtime / downtime
  -r, --reverse         reverse order
  -s, --seconds         output time in seconds and epoch
  -S SINCE, --since=SINCE
                        restric since this register number
  -t, --table           enumerate system life as table
  --tsince=TIMESTAMP    restrict since this timestamp
  --tuntil=TIMESTAMP    restrict until this timestamp
  -U UNTIL, --until=UNTIL
                        restrict until this register number
  -u, --uptime          order by uptime
  -v, --verbose         verbose output
  -V, --version         show version
  -x, --silent          update values into db without output


-h, --help
  Print a quick reference of the command line parameters.

  Examples:
         tuptime -h
         tuptime --help


-c, --ckernel
  Order table or list by kernel name. Therefore, only works in conjunction 
  with (-k) and (-t) or (-l) options.

  Examples:
         tuptime -ckl
         tuptime -ckt
         tuptime -t --ckernel
         tuptime -l --ckernel


--csv
  Report in csv format.

  Examples:
         tuptime --csv
         tuptime --csv -t


-d <DATE_FORMAT>, --date=<DATE_FORMAT>
  Change the date format. By default it's printed based on system locales.
  Allow values are:

	%a	Weekday as locale’s abbreviated name.
	%A	Weekday as locale’s full name.
	%w	Weekday as a decimal number, where 0 is Sunday and 6 is 
		Saturday.
	%d	Day of the month as a zero-padded decimal number.
	%b	Month as locale’s abbreviated name.
	%B	Month as locale’s full name.
	%m	Month as a zero-padded decimal number.
	%y	Year without century as a zero-padded decimal number.
	%Y	Year with century as a decimal number.
	%H	Hour (24-hour clock) as a zero-padded decimal number.
	%I	Hour (12-hour clock) as a zero-padded decimal number.
	%p	Locale’s equivalent of either AM or PM.
	%M	Minute as a zero-padded decimal number.
	%S	Second as a zero-padded decimal number.
	%f	Microsecond as a decimal number, zero-padded on the left.
	%z	UTC offset in the form +HHMM or -HHMM (empty string if the 
		the object is naive).
	%Z	Time zone name (empty string if the object is naive).
	%j	Day of the year as a zero-padded decimal number.
	%U	Week number of the year (Sunday as the first day of the week) 
		as a zero padded decimal number. All days in a new year 
		preceding the first Sunday are considered to be in week 0.
	%W	Week number of the year (Monday as the first day of the week) 
		as a decimal number. All days in a new year preceding the 
		first Monday are considered to be in week 0.
	%c	Locale’s appropriate date and time representation.
	%x	Locale’s appropriate date representation.
	%X	Locale’s appropriate time representation.
	%%	A literal '%' character.


  Examples:
         tuptime -d '%X %x'  # (Default)
         tuptime -d '%H:%M:%S   %m-%d-%Y'  # British style
         tuptime -d '%H:%M:%S   %d-%b-%Y'  # Spanish style


-e, --end
  Order table or list by end status at power off. Therefore, only works 
  in conjunction with (-t) or (-l) options.

  Examples:
         tuptime -te
         tuptime -le
         tuptime -t --end
         tuptime -l --end


-f <FILE>, --filedb=<FILE>
  Define an alternative database file. Default is located in 
  '/var/lib/tuptime/tuptime.db'

  Examples:
         tuptime -f /var/lib/tuptime/tuptime.db  # (Default)
         tuptime -f /tmp/test1.db
         tuptime --filedb /tmp/test2.db

  
-g, --graceful
  Register last time in the db as a graceful shutdown. This option is the way
  that tuptime have for know if is a good or a bad shutdown, like a hang of the
  system, for example. This is used in the init.d and systemd files at the 
  shutdown process.

  Examples:
         tuptime -g
         tuptime --graceful


-k, --kernel
  Add kernel information to the output.

  Examples:
         tuptime -k
         tuptime -lk
         tuptime --kernel
         tuptime -t --kernel


-l, --list
  Enumerate as list each startup number, startup date, uptime, shutdown date, 
  end status and offtime. Multiple order options can be combined together.

  Examples:
         tuptime -l
         tuptime --list


-n, --noup
  Avoid update values in the db with the current btime, uptime, etc. Useful 
  when reporting modified db files.

  Examples:
         tuptime -n
         tuptime --noup


-o, --offtime
  Order table or list by offtime / downtime. Therefore, only works in conjunction with 
  (-t) or (-l) options.

  Examples:
         tuptime -to
         tuptime -lo
         tuptime -t --offtime
         tuptime -l --offtime


-r, --reverse
  Reverse the order for table or list output. Therefore, only works in conjunction with 
  any of (-t), (-l), (-e), (-o), (-u) and (-c) options.

  Examples:
         tuptime -tr
         tuptime -lur
         tuptime -teo --reverse
         tuptime -l --reverse


-s, --seconds
  Change default human readable date style and print times in seconds and
  dates in epoch.

  Examples:
         tuptime -s
         tuptime --seconds


-S <SINCE>, --since <SINCE>
  Calculate values only since this startup number. Take it from (-t) table or
  (-l) list reports.

  Examples:
          tuptime -S 34
          tuptime --since 22
          tuptime -s -1

  
-t, --table
  Enumerate as table each startup number, startup date, uptime, shutdown date, 
  end status and downtime. Multiple order options can be combined together.

  Examples:
         tuptime -t
         tuptime --table


--tsince <TIMESTAMP>
  Restrict report since the given timestamp.
  Options (-S) and (-U) have precedence over this one.

  Examples:
         tuptime --tsince 1454998872
         tuptime --tsince -1000


--tuntil <TIMESTAMP>
  Restrict report until the given timestamp.
  Options (-S) and (-U) have precedence over this one.

  Examples:
         tuptime --tuntil 1454999619
         tuptime --tuntil -1000


-u, --uptime
  Order table or list by uptime. Therefore, only works in conjunction with 
  (-t) or (-l) options.

  Examples:
         tuptime -tu
         tuptime -lu
         tuptime -t --uptime
         tuptime -l --uptime


-U <UNTIL>, --until <UNTIL>
  Calculate values only until this startup number. Take it from (-t) table or
  (-l) list reports.

  Examples:
          tuptime -U 45
          tuptime --since 11
          tuptime -S -10


-v, --verbose
  Print information about the internals of tuptime. It's good for debugging 
  how it gets the variables.

  Examples:
         tuptime -v
         tuptime --verbose


-V, --version:
  Print version number and exit.

  Examples:
         tuptime -V
         tuptime --version


-x, --silent
  Any output is printed. Only update values and save them into disk.

  Examples:
         tuptime -x
         tuptime --silent



======================
| Schedule execution |
======================

It's importat to have a schedule execution. If the init or systemd scripts
are installed as it needs, the program only update values at startup and 
shutdown, but if the system fails, hangs or whatever, the uptime time will
be lost. Be sure that the cron entry is installed as expected.



==================
| Default output |
==================

System startups:	
 Total number of system startups from a since date. Until is joined if
 is used in a narrow range.

System shutdowns:
  Total number of shutdowns done correctly or incorrectly.

System uptime:
  Percentage of uptime and time counter.

System downtime:
  Percentage of downtime and time counter.

System life:
  Time counter since first startup date until last. Arguments --tsince or
  --tuntil can delimit a narrow range.

Largest uptime:
Shortest uptime:
Largest downtime:
Shortest downtime:
  Time counter and date with the large/short uptime complete register. Narrow
  ranges can produce incomplete registers and are excluded.

Average uptime:
Average downtime: 
  Time counter with the average time. Narrow ranges are included.

Current uptime:
  Actual time counter and date. Always is update, even if no update is used.



=============================================
| DB format changes from 2.x to 3.x version |
=============================================

If this error appears:

...(a few lines)...
sqlite3.OperationalError: no such column: endst

or:

...(a few lines)...
    db_rows[-1][4] = opt.endst
IndexError: list assignment index out of range

Is because the database have the format of the 2.x release. For migrate it, 
please, execute the script "db-tuptime-migrate.sh" which is located at:

https://github.com/rfrail3/tuptime/blob/master/scripts/db-tuptime-migrate.sh
 
 

==================
| Database Specs |
==================

Tuptime use a sqlite3 database located in "/var/lib/tuptime/tuptime.db" with
the following format:

tuptime (btime integer, 
         uptime real, 
         offbtime integer, 
         endst integer, 
         downtime real, 
         kernel text)

btime    Startup date in epoch
uptime   Uptime seconds  
offbtime Shutdown date in epoch
endst    Type of shutdown [1 ok | 0 bad]
downtime Downtime seconds
kernel   Name of the kernel

The number of startup sequency is extracted from "rowid", the signed integer 
key that uniquely identifies the row within its table in sqlite.

For reset all the values, simply detele the database file.

Is it possible to query and modify it directly. But if a complete row is
deleted and the db is not recreate completely (vacuum), rowid keep the real
information about startup number. Tuptime will advert about it if the verbose
mode is enabled.



================
| Some Toughts |
================

Tuptime can be executed with 'root' user, but it's recomendable the use of an
unprivileged user, like 'tuptime' as the installation section reflects for
avoid security problems. In any case, if the database file is not writable by
the user that execute tuptime, the changes are not saved. This situation is
covered for print values, but not for update database, for that reason, a 
user who can write in the db file must to execuete tuptime for update values
at startup and shutdown at least.

Kernel name is registered each time that tuptime update values. If ksplice is
used to update the kernel, last kernel will have the whole time asignement
since the last system start.

As usual, if the system have configured a time zone with daylight saving time
(DST), for avoid problems when the time change, the real time clock (RTC) 
should have set to universal time coordinated (UTC), not local time. Check it
with 'timedatectl' command.
http://tldp.org/HOWTO/Clock-2.html
