tailog 0.3.7 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ddf6171d97f0768c334605909704196c9b390d7b
4
- data.tar.gz: ee4aebfc0cb499bcca30e6c380e98c56cd3d38ee
3
+ metadata.gz: e059546fe3ba51e4d77e16ecec8e8415849af454
4
+ data.tar.gz: b3ae7620423132949c16eb327e5f8e56a280fb89
5
5
  SHA512:
6
- metadata.gz: 1c2a04e4a0d9dc5c935fd6acc85b0e79330a5eebabbb4e697a13c1b9f2d8bc0776151895d7458ea62bd23f43d1e349ef0b611a847f73ed412190d53ffed6d589
7
- data.tar.gz: 8642564b2328d80ab17e588b2388be561b7fbdc86a4d49a1b0e0fe80075d4cbcc6877439563e83052b05c8706112c6e2dc491108100043268783112d000a049a
6
+ metadata.gz: 0afce3b55d7d34d91819a52a356846e58db3eb6ddc4e72e31b3240c76371a4b2bd93207d983247a0ab5734da94ae4089bd68ac9f3cf10fce201944eab14106bb
7
+ data.tar.gz: 143514a5dba6dd0519d1633961d7d44f52e92e60ceecde7108ac82a7cee2aa1c0555e5f4b97326e707e6eef4e7c7f705f8001b2e334560b0c59464b5b49b885a
@@ -15,14 +15,14 @@
15
15
  // Normal and then Bright
16
16
  ANSI_COLORS = [
17
17
  [
18
- { color: "8, 2, 0", 'class': "ansi-black" },
19
- { color: "228, 68, 41", 'class': "ansi-red" },
20
- { color: "0, 173, 101", 'class': "ansi-green" },
21
- { color: "254, 238, 0", 'class': "ansi-yellow" },
22
- { color: "0, 176, 234", 'class': "ansi-blue" },
23
- { color: "178, 128, 165", 'class': "ansi-magenta" },
24
- { color: "193, 233, 247", 'class': "ansi-cyan" },
25
- { color: "180, 177, 177", 'class': "ansi-white" }
18
+ { color: "27, 27, 27", 'class': "ansi-black" },
19
+ { color: "182, 80, 47", 'class': "ansi-red" },
20
+ { color: "141, 161, 88", 'class': "ansi-green" },
21
+ { color: "220, 175, 95", 'class': "ansi-yellow" },
22
+ { color: "126, 170, 199", 'class': "ansi-blue" },
23
+ { color: "176, 101, 152", 'class': "ansi-magenta" },
24
+ { color: "141, 220, 217", 'class': "ansi-cyan" },
25
+ { color: "217, 217, 217", 'class': "ansi-white" }
26
26
  ], [
27
27
  { color: "27, 27, 27", 'class': "ansi-bright-black" },
28
28
  { color: "182, 80, 47", 'class': "ansi-bright-red" },
@@ -0,0 +1,152 @@
1
+ /*
2
+ * jQuery Highlight plugin
3
+ *
4
+ * Based on highlight v3 by Johann Burkard
5
+ * http://johannburkard.de/blog/programming/javascript/highlight-javascript-text-higlighting-jquery-plugin.html
6
+ *
7
+ * Code a little bit refactored and cleaned (in my humble opinion).
8
+ * Most important changes:
9
+ * - has an option to highlight only entire words (wordsOnly - false by default),
10
+ * - has an option to be case sensitive (caseSensitive - false by default)
11
+ * - highlight element tag and class names can be specified in options
12
+ *
13
+ * Usage:
14
+ * // wrap every occurrence of text 'lorem' in content
15
+ * // with <span class='highlight'> (default options)
16
+ * $('#content').highlight('lorem');
17
+ *
18
+ * // search for and highlight more terms at once
19
+ * // so you can save some time on traversing DOM
20
+ * $('#content').highlight(['lorem', 'ipsum']);
21
+ * $('#content').highlight('lorem ipsum');
22
+ *
23
+ * // search only for entire word 'lorem'
24
+ * $('#content').highlight('lorem', { wordsOnly: true });
25
+ *
26
+ * // search only for the entire word 'C#'
27
+ * // and make sure that the word boundary can also
28
+ * // be a 'non-word' character, as well as a regex latin1 only boundary:
29
+ * $('#content').highlight('C#', { wordsOnly: true , wordsBoundary: '[\\b\\W]' });
30
+ *
31
+ * // don't ignore case during search of term 'lorem'
32
+ * $('#content').highlight('lorem', { caseSensitive: true });
33
+ *
34
+ * // wrap every occurrence of term 'ipsum' in content
35
+ * // with <em class='important'>
36
+ * $('#content').highlight('ipsum', { element: 'em', className: 'important' });
37
+ *
38
+ * // remove default highlight
39
+ * $('#content').unhighlight();
40
+ *
41
+ * // remove custom highlight
42
+ * $('#content').unhighlight({ element: 'em', className: 'important' });
43
+ *
44
+ *
45
+ * Copyright (c) 2009 Bartek Szopka
46
+ *
47
+ * Licensed under MIT license.
48
+ *
49
+ */
50
+
51
+ (function (factory) {
52
+ if (typeof define === 'function' && define.amd) {
53
+ // AMD. Register as an anonymous module.
54
+ define(['jquery'], factory);
55
+ } else if (typeof exports === 'object') {
56
+ // Node/CommonJS
57
+ factory(require('jquery'));
58
+ } else {
59
+ // Browser globals
60
+ factory(jQuery);
61
+ }
62
+ }(function (jQuery) {
63
+ jQuery.extend({
64
+ highlight: function (node, re, nodeName, className) {
65
+ if (node.nodeType === 3) {
66
+ var match = node.data.match(re);
67
+ if (match) {
68
+ // The new highlight Element Node
69
+ var highlight = document.createElement(nodeName || 'span');
70
+ highlight.className = className || 'highlight';
71
+ // Note that we use the captured value to find the real index
72
+ // of the match. This is because we do not want to include the matching word boundaries
73
+ var capturePos = node.data.indexOf( match[1] , match.index );
74
+
75
+ // Split the node and replace the matching wordnode
76
+ // with the highlighted node
77
+ var wordNode = node.splitText(capturePos);
78
+ wordNode.splitText(match[1].length);
79
+
80
+ var wordClone = wordNode.cloneNode(true);
81
+ highlight.appendChild(wordClone);
82
+ wordNode.parentNode.replaceChild(highlight, wordNode);
83
+ return 1; //skip added node in parent
84
+ }
85
+ } else if ((node.nodeType === 1 && node.childNodes) && // only element nodes that have children
86
+ !/(script|style)/i.test(node.tagName) && // ignore script and style nodes
87
+ !(node.tagName === nodeName.toUpperCase() && node.className === className)) { // skip if already highlighted
88
+ for (var i = 0; i < node.childNodes.length; i++) {
89
+ i += jQuery.highlight(node.childNodes[i], re, nodeName, className);
90
+ }
91
+ }
92
+ return 0;
93
+ }
94
+ });
95
+
96
+ jQuery.fn.unhighlight = function (options) {
97
+ var settings = {
98
+ className: 'highlight',
99
+ element: 'span'
100
+ };
101
+
102
+ jQuery.extend(settings, options);
103
+
104
+ return this.find(settings.element + '.' + settings.className).each(function () {
105
+ var parent = this.parentNode;
106
+ parent.replaceChild(this.firstChild, this);
107
+ parent.normalize();
108
+ }).end();
109
+ };
110
+
111
+ jQuery.fn.highlight = function (words, options) {
112
+ var settings = {
113
+ className: 'highlight',
114
+ element: 'span',
115
+ caseSensitive: false,
116
+ wordsOnly: false,
117
+ wordsBoundary: '\\b'
118
+ };
119
+
120
+ jQuery.extend(settings, options);
121
+
122
+ if (typeof words === 'string') {
123
+ words = [words];
124
+ }
125
+ words = jQuery.grep(words, function(word, i){
126
+ return word != '';
127
+ });
128
+ words = jQuery.map(words, function(word, i) {
129
+ return word.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
130
+ });
131
+
132
+ if (words.length === 0) {
133
+ return this;
134
+ };
135
+
136
+ var flag = settings.caseSensitive ? '' : 'i';
137
+ // The capture parenthesis will make sure we can match
138
+ // only the matching word
139
+ var pattern = '(' + words.join('|') + ')';
140
+ if (settings.wordsOnly) {
141
+ pattern =
142
+ (settings.wordsBoundaryStart || settings.wordsBoundary) +
143
+ pattern +
144
+ (settings.wordsBoundaryEnd || settings.wordsBoundary);
145
+ }
146
+ var re = new RegExp(pattern, flag);
147
+
148
+ return this.each(function () {
149
+ jQuery.highlight(this, re, settings.element, settings.className);
150
+ });
151
+ };
152
+ }));
@@ -9,6 +9,28 @@ p {
9
9
  margin: 0;
10
10
  }
11
11
 
12
+ .fixed-top-right {
13
+ position: fixed;
14
+ top: 25px;
15
+ right: 25px;
16
+ }
17
+
18
+ .settings-panel {
19
+ margin-top: 50px;
20
+ width: 320px;
21
+ box-shadow: 0 6px 12px rgba(0,0,0,.175);
22
+ }
23
+
24
+ .highlight-list {
25
+ margin-top: 5px;
26
+ }
27
+
28
+ .highlight-list span {
29
+ cursor: pointer;
30
+ margin-right: 5px;
31
+ font-size: 12px;
32
+ }
33
+
12
34
  .content-hover p:hover {
13
35
  background: #EEE;
14
36
  }
@@ -37,3 +59,7 @@ p {
37
59
  color: #a94442;
38
60
  border-bottom: 3px dashed #d9534f;
39
61
  }
62
+
63
+ .highlight {
64
+ background: #FFFF88;
65
+ }
data/app/views/layout.erb CHANGED
@@ -5,6 +5,7 @@
5
5
  <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.3/jquery.min.js"></script>
6
6
  <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery.form/3.51/jquery.form.js"></script>
7
7
  <script type="text/javascript" src="javascripts/ansi_up.js"></script>
8
+ <script type="text/javascript" src="javascripts/jquery.highlight.js"></script>
8
9
  <link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css">
9
10
  <link rel="stylesheet" type="text/css" href="stylesheets/application.css">
10
11
  </head>
@@ -7,23 +7,83 @@
7
7
  <h3 class="page-header"><%= file_path %></h3>
8
8
 
9
9
  <% File.open file_path do |file| %>
10
- <div id="content" class="content-hover"></div>
10
+ <div id="content" class="content content-hover"></div>
11
11
  <% end %>
12
12
 
13
- <a id="add_divider" class="btn btn-danger pull-right">Add Divider</a>
13
+ <a id="settings-toggle" class="btn btn-primary fixed-top-right"><i class="glyphicon glyphicon-cog"></i></a>
14
+
15
+ <div id="settings-panel" class="panel panel-info fixed-top-right settings-panel hidden">
16
+ <div class="panel-heading">Settings</div>
17
+ <div class="panel-body">
18
+ <div class="form-group btn-group">
19
+ <a id="add-divider" class="btn btn-default">Add Divider</a>
20
+ <a id="clear-logs" class="btn btn-default">Clear Logs</a>
21
+ </div>
22
+ <div class="form-group">
23
+ <div class="input-group">
24
+ <input id="highlight" type="text" class="form-control" placeholder="Keyword">
25
+ <span class="input-group-btn">
26
+ <button id="add-highlight" class="btn btn-default" type="button">Highlight!</button>
27
+ </span>
28
+ </div>
29
+ <div id="highlight-list" class="highlight-list"></div>
30
+ </div>
31
+ </div>
32
+ </div>
14
33
 
15
34
  <script type="text/javascript">
16
- window.fileSize = {};
17
- window.fileSizeDone = {};
18
- var $window = $(window),
19
- $document = $(document),
20
- $content = $("#content");
35
+ var $settingsPanel = $("#settings-panel");
36
+ $("#settings-toggle").click(function() {
37
+ $settingsPanel.toggleClass("hidden");
38
+ });
21
39
 
22
40
  var dividerId = 1;
23
- $("#add_divider").click(function() {
41
+ $("#add-divider").click(function() {
24
42
  $content.append('<span class="divider"> #' + dividerId++ + ' - ' + new Date() + '</span>');
25
43
  });
26
44
 
45
+ $("#clear-logs").click(function() {
46
+ $content.html('');
47
+ });
48
+
49
+ var $highlight = $("#highlight"),
50
+ $highlightList = $("#highlight-list");
51
+
52
+ function rawHighlight(keyword) {
53
+ $content.highlight(keyword, { className: 'highlight highlight-' + keyword });
54
+ }
55
+
56
+ function rawUnhighlight(keyword) {
57
+ $content.unhighlight({ className: 'highlight-' + keyword });
58
+ }
59
+
60
+ function highlight(keyword) {
61
+ if ($highlightList.find('.highlight-' + keyword).length > 0) return;
62
+ rawHighlight(keyword);
63
+ $highlightList.append('<span class="label label-primary highlight-' + keyword + ' toggle-highlight">' + keyword + '</span>');
64
+ }
65
+
66
+ $highlight.keypress(function(event) {
67
+ if ((event.keyCode || event.which) === 13) {
68
+ highlight($highlight.val());
69
+ }
70
+ });
71
+ $("#add-highlight").click(function() {
72
+ highlight($highlight.val());
73
+ });
74
+
75
+ $("#highlight-list").on("click", ".toggle-highlight", function(event) {
76
+ var $this = $(this),
77
+ keyword = $this.text();
78
+ $this.data('hidden') ? rawHighlight(keyword) : rawUnhighlight(keyword);
79
+ $this.data('hidden', !$this.data('hidden'));
80
+ });
81
+
82
+ window.fileSize = {};
83
+ window.fileSizeDone = {};
84
+ var $window = $(window),
85
+ $document = $(document),
86
+ $content = $("#content");
27
87
  function loadMore() {
28
88
  $.post(window.location.href, { seek: window.fileSize }, function(json) {
29
89
  try {
@@ -36,10 +96,16 @@
36
96
 
37
97
  if (!data.content) return;
38
98
  var shouldScrollToBottom = $window.scrollTop() + $window.height() == $document.height();
99
+
39
100
  $content
40
101
  .append('<span class="text-info">' + data.server_hostname + ' - ' + data.file_size + '</span>')
41
102
  .append(ansi_up.ansi_to_html(data.content));
42
103
 
104
+ $highlightList.find("span").each(function(index, node) {
105
+ var $node = $(node);
106
+ $node.data('hidden') || rawHighlight($node.text());
107
+ });
108
+
43
109
  if (shouldScrollToBottom) {
44
110
  $window.scrollTop($document.height() - $window.height());
45
111
  }
@@ -0,0 +1,36 @@
1
+ module Tailog
2
+ class Eval
3
+ class << self
4
+ attr_accessor :blacklist
5
+ end
6
+
7
+ self.blacklist = %w(/tailog)
8
+
9
+ def initialize app
10
+ @app = app
11
+ end
12
+
13
+ def call env
14
+ if skip_call? env
15
+ @app.call(env)
16
+ else
17
+ before = env["HTTP_TAILOG_EVAL_BEFORE"].presence
18
+ after = env["HTTP_TAILOG_EVAL_AFTER"].presence
19
+
20
+ eval before if before
21
+ response = @app.call(env)
22
+ eval after if after
23
+
24
+ response
25
+ end
26
+ end
27
+
28
+ private
29
+
30
+ def skip_call? env
31
+ Tailog::Eval.blacklist.any? do |path|
32
+ env["PATH_INFO"].start_with? path
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,24 @@
1
+ module Tailog
2
+ class RequestId
3
+ def initialize app
4
+ @app = app
5
+ end
6
+
7
+ def call env
8
+ Tailog.request_id = external_request_id(env) || internal_request_id
9
+ @app.call(env).tap do |_status, headers, _body|
10
+ headers["X-Request-Id"] = Tailog.request_id
11
+ end
12
+ end
13
+
14
+ private
15
+
16
+ def external_request_id env
17
+ env["HTTP_X_REQUEST_ID"].presence
18
+ end
19
+
20
+ def internal_request_id
21
+ SecureRandom.uuid
22
+ end
23
+ end
24
+ end
@@ -1,3 +1,3 @@
1
1
  module Tailog
2
- VERSION = "0.3.7"
2
+ VERSION = "0.4.0"
3
3
  end
@@ -1,22 +1,17 @@
1
1
  require 'active_support/core_ext/string'
2
- require 'active_support/configurable'
3
2
  require 'securerandom'
4
3
  require 'logger'
5
4
 
6
5
  module Tailog
7
6
  module WatchMethods
8
- include ActiveSupport::Configurable
9
-
10
7
  class << self
11
- attr_accessor :request_id
12
-
13
8
  def logger
14
9
  return @logger if @logger
15
10
  @logger = Logger.new(File.join Tailog.log_path, "watch_methods.log")
16
11
  @logger.formatter = proc do |severity, datetime, progname, message|
17
12
  content = ""
18
13
  content << "[#{datetime.strftime("%Y-%m-%d %H:%M:%S")}]"
19
- content << "[#{Tailog::WatchMethods.request_id}]" if Tailog::WatchMethods.request_id
14
+ content << "[#{Tailog.request_id}]" if Tailog.request_id
20
15
  content << " #{severity.rjust(5)}"
21
16
  content << " (#{progname})" if progname
22
17
  content << ": #{message.gsub(/\n\s*/, " ")}"
@@ -27,68 +22,63 @@ module Tailog
27
22
  end
28
23
  end
29
24
 
30
- class RequestId
31
- def initialize(app)
32
- @app = app
33
- end
34
-
35
- def call(env)
36
- Tailog::WatchMethods.request_id = external_request_id(env) || internal_request_id
37
- @app.call(env).tap do |_status, headers, _body|
38
- headers["X-Request-Id"] = Tailog::WatchMethods.request_id
39
- end
40
- end
41
-
42
- private
43
-
44
- def external_request_id(env)
45
- if request_id = env["HTTP_X_REQUEST_ID"].presence
46
- request_id.gsub(/[^\w\-]/, "").first(255)
47
- end
48
- end
49
-
50
- def internal_request_id
51
- SecureRandom.uuid
52
- end
53
- end
54
-
55
- def inject_constants targets
25
+ def inject targets
56
26
  targets.each do |target|
57
27
  begin
58
- target.constantize.instance_methods(false).each do |method|
59
- inject_instance_method "#{target}##{method}"
60
- end
61
- target.constantize.methods(false).each do |method|
62
- inject_class_method "#{target}.#{method}"
28
+ if target.include? "#"
29
+ inject_instance_method target
30
+ elsif target.include? "."
31
+ inject_class_method target
32
+ else
33
+ inject_constant target
63
34
  end
64
35
  rescue => error
65
- WatchMethods.logger.error "Inject constant `#{target}' failed: #{error.class}: #{error.message}"
36
+ WatchMethods.logger.error "Inject #{target} FAILED: #{error.class}: #{error.message}"
66
37
  end
67
38
  end
68
39
  end
69
40
 
70
- def inject_methods targets
41
+ def cleanup targets
71
42
  targets.each do |target|
72
- begin
73
- if target.include? "#"
74
- inject_instance_method target
75
- else
76
- inject_class_method target
77
- end
78
- rescue => error
79
- WatchMethods.logger.error "Inject method `#{target}' failed: #{error.class}: #{error.message}"
43
+ if target.include? "#"
44
+ cleanup_instance_method target
45
+ elsif target.include? "."
46
+ cleanup_class_method target
47
+ else
48
+ cleanup_constant target
80
49
  end
81
50
  end
82
51
  end
83
52
 
84
53
  private
85
54
 
55
+ RAW_METHOD_PREFIX = "watch_method_raw_"
56
+
57
+ def raw_method? method
58
+ method.to_s.start_with? RAW_METHOD_PREFIX
59
+ end
60
+
61
+ def inject_constant target
62
+ constant = target.constantize
63
+ constant.instance_methods(false).each do |method|
64
+ inject_instance_method "#{target}##{method}" unless raw_method? method
65
+ end
66
+ constant.methods(false).each do |method|
67
+ inject_class_method "#{target}.#{method}" unless raw_method? method
68
+ end
69
+ end
70
+
71
+ def cleanup_constant target
72
+ target.constantize.instance_methods(false).each do |method|
73
+ cleanup_instance_method "#{target}##{method}" unless raw_method? method
74
+ end
75
+ target.constantize.methods(false).each do |method|
76
+ cleanup_class_method "#{target}.#{method}" unless raw_method? method
77
+ end
78
+ end
79
+
86
80
  def inject_class_method target
87
- klass, _, method = if target.include? "."
88
- target.rpartition(".")
89
- else
90
- target.rpartition("::")
91
- end
81
+ klass, _, method = target.rpartition(".")
92
82
  klass.constantize.class_eval <<-EOS, __FILE__, __LINE__
93
83
  class << self
94
84
  #{build_watch_method target, method}
@@ -96,6 +86,15 @@ module Tailog
96
86
  EOS
97
87
  end
98
88
 
89
+ def cleanup_class_method target
90
+ klass, _, method = target.rpartition(".")
91
+ klass.constantize.class_eval <<-EOS, __FILE__, __LINE__
92
+ class << self
93
+ #{build_cleanup_method target, method}
94
+ end
95
+ EOS
96
+ end
97
+
99
98
  def inject_instance_method target
100
99
  klass, _, method = target.rpartition("#")
101
100
  klass.constantize.class_eval <<-EOS, __FILE__, __LINE__
@@ -103,8 +102,15 @@ module Tailog
103
102
  EOS
104
103
  end
105
104
 
105
+ def cleanup_instance_method target
106
+ klass, _, method = target.rpartition("#")
107
+ klass.constantize.class_eval <<-EOS, __FILE__, __LINE__
108
+ #{build_cleanup_method target, method}
109
+ EOS
110
+ end
111
+
106
112
  def build_watch_method target, method
107
- raw_method = "watch_method_raw_#{method}"
113
+ raw_method = "#{RAW_METHOD_PREFIX}#{method}"
108
114
  return <<-EOS
109
115
  unless instance_methods.include?(:#{raw_method})
110
116
  alias_method :#{raw_method}, :#{method}
@@ -124,5 +130,15 @@ module Tailog
124
130
  end
125
131
  EOS
126
132
  end
133
+
134
+ def build_cleanup_method target, method
135
+ raw_method = "#{RAW_METHOD_PREFIX}#{method}"
136
+ return <<-EOS
137
+ if method_defined? :#{raw_method}
138
+ alias_method :#{method}, :#{raw_method}
139
+ remove_method :#{raw_method}
140
+ end
141
+ EOS
142
+ end
127
143
  end
128
144
  end
data/lib/tailog.rb CHANGED
@@ -1,4 +1,6 @@
1
1
  require 'tailog/version'
2
+ require 'tailog/eval'
3
+ require 'tailog/request_id'
2
4
  require 'tailog/watch_methods'
3
5
  require 'tailog/ext/file'
4
6
 
@@ -11,7 +13,7 @@ module Tailog
11
13
  extend Tailog::WatchMethods
12
14
 
13
15
  class << self
14
- attr_accessor :log_path
16
+ attr_accessor :log_path, :request_id
15
17
 
16
18
  def server_hostname
17
19
  @server_hostname ||= Socket.gethostname
data/tailog.gemspec CHANGED
@@ -27,6 +27,8 @@ Gem::Specification.new do |spec|
27
27
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
28
28
  spec.require_paths = ["lib"]
29
29
 
30
+ spec.add_dependency "sinatra", "~> 1.4"
31
+
30
32
  spec.add_development_dependency "bundler", "~> 1.11"
31
33
  spec.add_development_dependency "rake", "~> 10.0"
32
34
  end
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tailog
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.7
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - bbtfr
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-04-22 00:00:00.000000000 Z
11
+ date: 2016-04-25 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: sinatra
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.4'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.4'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: bundler
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -51,6 +65,7 @@ files:
51
65
  - README.md
52
66
  - Rakefile
53
67
  - app/assets/javascripts/ansi_up.js
68
+ - app/assets/javascripts/jquery.highlight.js
54
69
  - app/assets/stylesheets/application.css
55
70
  - app/views/env.erb
56
71
  - app/views/error.erb
@@ -63,7 +78,9 @@ files:
63
78
  - bin/console
64
79
  - bin/setup
65
80
  - lib/tailog.rb
81
+ - lib/tailog/eval.rb
66
82
  - lib/tailog/ext/file.rb
83
+ - lib/tailog/request_id.rb
67
84
  - lib/tailog/version.rb
68
85
  - lib/tailog/watch_methods.rb
69
86
  - tailog.gemspec