Timelines from Emacs org-mode
Feb 12, 2011I use Emacs org-mode for all of my notes and todos. My workflow for handling outages and other immediate issues is:
- Create and clock-in an entry for the problem.
- Work the issue and keep brief timestamped notes under that entry.
- Generate a timeline afterward.
Here’s a fictional example, typical of a hotline:
* Trouble Tickets
** CLOSED RT00012345: HIGH PRIORITY!!1! teh app is down, please do the necessary
- State "CLOSED" from "STARTED" [2010-09-29 Wed 19:16]
- State "STARTED" from "WAITING" [2010-09-29 Wed 19:00]
- [2010-09-29 Wed 19:00] received callback from user
- [2010-09-29 Wed 19:05] user reports inet, phone & cable tv down
- [2010-09-29 Wed 19:06] confirmed issue resolved
- [2010-09-29 Wed 19:16] closed... PEBCAK
- State "WAITING" from "STARTED" [2010-09-29 Wed 18:10]
pending callback from reporting user
- State "STARTED" from "TODO" [2010-09-29 Wed 18:00]
- [2010-09-29 Wed 18:00] started checkout
- [2010-09-29 Wed 18:01] confirmed- no downtime scheduled
per http://gdc (global downtime calendar)
- [2010-09-29 Wed 18:01] confirmed- no open issues reported by NOC
per x5900 hotline, spoke w/Ketur S.
- [2010-09-29 Wed 18:02] confirmed- no events in site survey heatmap
- [2010-09-29 Wed 18:04] app farm checkout OKAY, local avg RTT 11ms
- [2010-09-29 Wed 18:06] called originating user, left vmail.
:CLOCK:
CLOCK: [2010-09-29 Wed 19:00]--[2010-09-29 Wed 19:16]
CLOCK: [2010-09-29 Wed 18:00]--[2010-09-29 Wed 18:10]
:END:
And the resulting timeline looks like:
* CLOSED RT00012345: HIGH PRIORITY!!1! teh app is down, please do the necessary
- [2010-09-29 Wed 18:00] started checkout
- [2010-09-29 Wed 18:01] confirmed- no downtime scheduled
- [2010-09-29 Wed 18:01] confirmed- no open issues reported by NOC
- [2010-09-29 Wed 18:02] confirmed- no events in site survey heatmap
- [2010-09-29 Wed 18:04] app farm checkout OKAY, local avg RTT 11ms
- [2010-09-29 Wed 18:06] called originating user, left vmail.
- [2010-09-29 Wed 19:00] received callback from user
- [2010-09-29 Wed 19:05] user reports inet, phone & cable tv down
- [2010-09-29 Wed 19:06] confirmed issue resolved
- [2010-09-29 Wed 19:16] closed... PEBCAK
To get this, I define a format for note and a quick keyboard shortcut for it:
(push '("!" "Timestamped note to current clock" item (clock) " - %U %?n%in")
org-capture-templates)
(global-set-key (kbd "C-c o !") '(lambda () (interactive) (org-capture nil "!")))
and a routine that generates a timeline from the current heading
(defun rel-org-maybe-copy-ts-item (buf)
"Copy current line to specified buffer if line is a timestamped item"
(when (save-excursion
(beginning-of-line 1)
(skip-chars-forward "t ")
(looking-at (concat "- " org-ts-regexp3)))
(let ((l (buffer-substring (line-beginning-position) (line-end-position))))
(with-current-buffer (get-buffer-create buf)
(insert l "n")))))
(defun rel-org-extract-timeline ()
"Iterate over the current heading collecting the first line of
timestamped items into a sorted timeline in a buffer"
(interactive)
(save-excursion
(org-back-to-heading)
(unless (> (org-current-level) 1) (error "Must be at sublevel"))
(let ((bufname "timeline")
(heading (org-get-heading t))
(clktime (apply 'encode-time (append `(0 ,(org-clock-sum-current-item) 0) (nthcdr 3 (decode-time)))))
(start (point))
(end (save-excursion (org-end-of-subtree :invisible-OK t))))
(with-current-buffer (get-buffer-create bufname)
(insert "* " heading "n")
(org-entry-put (point) "ClockedTime" (format-time-string "%R" clktime) "n"))
(while (progn (forward-line 1) (< (point) end))
(funcall 'rel-org-maybe-copy-ts-item bufname))
(with-current-buffer (get-buffer-create bufname)
(org-back-to-heading)
(forward-line 1)
(org-sort-entries-or-items :sorting-type ?t)))))