tailog 0.3.7 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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