Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
6101c3c
commit c901eb8
Showing
24 changed files
with
393 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
// Action Cable provides the framework to deal with WebSockets in Rails. | ||
// You can generate new channels where WebSocket features live using the `rails generate channel` command. | ||
// | ||
//= require action_cable | ||
//= require_self | ||
//= require_tree ./channels | ||
|
||
(function() { | ||
this.App || (this.App = {}); | ||
|
||
App.cable = ActionCable.createConsumer(); | ||
|
||
}).call(this); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
App.redis_log = App.cable.subscriptions.create "RedisLogChannel", | ||
connected: -> | ||
# Called when the subscription is ready for use on the server | ||
|
||
disconnected: -> | ||
# Called when the subscription has been terminated by the server | ||
|
||
received: (data) -> | ||
# Called when there's incoming data on the websocket for this channel | ||
|
||
new: -> | ||
@perform 'new' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# Place all the behaviors and hooks related to the matching controller here. | ||
# All this logic will automatically be available in application.js. | ||
# You can use CoffeeScript in this file: http://coffeescript.org/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
// Place all the styles related to the RedisLog controller here. | ||
// They will automatically be included in application.css. | ||
// You can use Sass (SCSS) here: http://sass-lang.com/ | ||
|
||
.square-borders { | ||
border-radius: 0px !important; | ||
margin-bottom: -1px; | ||
} | ||
.list-item-label { | ||
background-color: #f5f5f5 !important; | ||
display:table !important; | ||
width:100%; | ||
table-layout: fixed; | ||
} | ||
.list-item-label > a { | ||
overflow: hidden; | ||
white-space: nowrap; | ||
display: table-cell; | ||
text-overflow: ellipsis; | ||
} | ||
.list-item-label:hover > a, .list-item-label > a:hover { | ||
text-decoration: none; | ||
} | ||
|
||
.list-item-label > div { | ||
display: table-cell; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
class RedisLogChannel < ApplicationCable::Channel | ||
def subscribed | ||
# binding.irb | ||
stream_from "redis_log_channel" if !current_user.nil? && current_user.has_role?(:developer) | ||
end | ||
|
||
def unsubscribed | ||
# Any cleanup needed when channel is unsubscribed | ||
end | ||
|
||
def new | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
class RedisLogController < ApplicationController | ||
before_action :authenticate_user! | ||
before_action :verify_developer | ||
|
||
def by_user | ||
user_id = params[:id] | ||
@sessions = redis.zrevrange("user_sessions/#{user_id}", 0, 20).map do |session_id| | ||
requests = redis.zrange("session/#{session_id}/requests", 0, 20, with_scores: true) | ||
redis.hgetall("session/#{session_id}").merge({ | ||
id: session_id, | ||
user_id: user_id, | ||
count: requests.length, | ||
requests: requests.map { |request_id, timestamp| | ||
redis.hgetall("request/#{timestamp}/#{request_id}").merge({ | ||
headers: redis.hgetall("request/#{timestamp}/#{request_id}/headers"), | ||
params: redis.hgetall("request/#{timestamp}/#{request_id}/params"), | ||
exception: redis.hgetall("request/#{timestamp}/#{request_id}/exception"), | ||
timestamp: timestamp, | ||
request_id: request_id, | ||
key: "#{timestamp.to_s.gsub('.', '-')}-#{request_id}" | ||
})} | ||
}) | ||
end | ||
render :user_sessions | ||
end | ||
|
||
def index | ||
@requests = redis.zrevrange("requests", 1, 11, with_scores: true).map do |request_id, timestamp| | ||
redis.hgetall("request/#{timestamp}/#{request_id}").merge({ | ||
headers: redis.hgetall("request/#{timestamp}/#{request_id}/headers"), | ||
params: redis.hgetall("request/#{timestamp}/#{request_id}/params"), | ||
exception: redis.hgetall("request/#{timestamp}/#{request_id}/exception"), | ||
timestamp: timestamp, | ||
request_id: request_id, | ||
key: "#{timestamp.to_s.gsub('.', '-')}-#{request_id}" | ||
}) | ||
end | ||
end | ||
|
||
def by_session | ||
session_id = params[:id] | ||
@requests = redis.zrange("session/#{session_id}/requests", 0, 20, with_scores: true).map do |request_id, timestamp| | ||
redis.hgetall("request/#{timestamp}/#{request_id}").merge({ | ||
headers: redis.hgetall("request/#{timestamp}/#{request_id}/headers"), | ||
params: redis.hgetall("request/#{timestamp}/#{request_id}/params"), | ||
exception: redis.hgetall("request/#{timestamp}/#{request_id}/exception"), | ||
timestamp: timestamp, | ||
request_id: request_id, | ||
key: "#{timestamp.to_s.gsub('.', '-')}-#{request_id}" | ||
}) | ||
end | ||
|
||
render :index | ||
end | ||
|
||
def by_status | ||
status = params[:status] | ||
@requests = redis.zrevrange("requests/status/#{status}", 0, 20, with_scores: true).map do |request_id, timestamp| | ||
redis.hgetall("request/#{timestamp}/#{request_id}").merge({ | ||
headers: redis.hgetall("request/#{timestamp}/#{request_id}/headers"), | ||
params: redis.hgetall("request/#{timestamp}/#{request_id}/params"), | ||
exception: redis.hgetall("request/#{timestamp}/#{request_id}/exception"), | ||
timestamp: timestamp, | ||
request_id: request_id, | ||
key: "#{timestamp.to_s.gsub('.', '-')}-#{request_id}" | ||
}) | ||
end | ||
render :index | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
module RedisLogHelper | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,3 +7,4 @@ import './posts'; | |
import './post'; | ||
import './topbar'; | ||
import './status'; | ||
import './redis_logs'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import { route } from '../util'; | ||
import cable from './cable'; | ||
|
||
/* TODO: Add websockets to the other pages */ | ||
let redis; | ||
route('/redis_log/index', () => { | ||
redis = cable.subscriptions.create('RedisLogChannel', { | ||
received(data) { | ||
var matched_log = $('#logs div[data-log-id="'+ data.key +'"]'); | ||
console.log($.parseHTML(data.html)[1]); | ||
if (matched_log.length > 0) { | ||
console.log(matched_log); | ||
matched_log[0].replaceWith($.parseHTML(data.html)[1]); | ||
} else { | ||
$("#logs").prepend($.parseHTML(data.html)[1]); | ||
} | ||
} | ||
}); | ||
}, () => { | ||
if (!redis) { | ||
return; | ||
} | ||
redis.unsubscribe(); | ||
redis = null; | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
class RedisLogJob < ApplicationJob | ||
queue_as :default | ||
|
||
def perform(request_id, timestamp) | ||
info = redis.hgetall("request/#{timestamp}/#{request_id}").merge({ | ||
headers: redis.hgetall("request/#{timestamp}/#{request_id}/headers"), | ||
params: redis.hgetall("request/#{timestamp}/#{request_id}/params"), | ||
exception: redis.hgetall("request/#{timestamp}/#{request_id}/exception"), | ||
timestamp: timestamp, | ||
request_id: request_id, | ||
key: "#{timestamp.to_s.gsub('.', '-')}-#{request_id}" | ||
}) | ||
ActionCable.server.broadcast "redis_log_channel", key: "#{timestamp.to_s.gsub('.', '-')}-#{request_id}", | ||
html: ApplicationController.render( | ||
template: 'redis_log/_row', | ||
locals: { req: info, wrapped: true }, | ||
layout: nil | ||
) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
<span class="text-<%= req['status'].to_i == 200 ? 'success' : 'danger' %>" href="#<%= req[:key] %>"> | ||
<%= render 'redis_log/user', impersonator_id: req['impersonator_id'], user_id: req['user_id'], session_id: req['session_id'] %> | ||
<code><%= link_to req['status'], redis_log_by_status_path(status: req['status']), style: 'display: inline;' %></code> <%= req['method'] %> <%= req['path'] %> | ||
</span> | ||
<div class="pull-right"> | ||
<code> | ||
<span style="display:inline-block;"> | ||
<%= Time.at(req[:timestamp]).strftime("%-y/%-m/%-d %-H:%M:%S.%-3N") %> | ||
</span> · <span style="display:inline-block;"> | ||
<i class="fas fa-database" title="DB time"></i> | ||
<%= number_with_precision(req['db_runtime'].to_f, precision: 3).rjust(7, "\u00A0") %>s | ||
· <i class="fas fa-desktop" title="View time"></i> | ||
<%= number_with_precision(req['view_runtime'].to_f, precision: 3).rjust(7, "\u00A0") %>s | ||
</span> | ||
</code> | ||
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
<table class="table"> | ||
<% params.each do |k, v| %> | ||
<tr> | ||
<td><%= k %></td> | ||
<td> | ||
<% if v.include?("\n") %> | ||
<pre style="overflow:scroll;max-height:20em;"><%= raw(sanitize(v).gsub("\n", "<br>")) %></pre> | ||
<% elsif v.nil? %> | ||
<code>nil</code> | ||
<% else %> | ||
<code><%= v %></code> | ||
<% end %> | ||
</td> | ||
</tr> | ||
<% end %> | ||
</table> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
<% wrapped ||= false %> | ||
<% if wrapped %><div data-log-id="<%= req[:key] %>"><% end %> | ||
<li class="list-group-item list-item-label" data-toggle="collapse" role="button" aria-expanded="false" aria-controls="<%= req[:key] %>" href="#<%= req[:key] %>"> | ||
<%= render 'redis_log/header', req: req %> | ||
</li> | ||
<div class="collapse" style="margin-bottom:-1px" id="<%= req[:key] %>"> | ||
<li class="list-group-item square-borders"> | ||
<p> | ||
<%= link_to "session", redis_log_by_session_path(id: req['session_id']) %> | | ||
<%= link_to "user", redis_log_by_user_path(id: req['user_id']) %> | ||
</p> | ||
<h4><code><%= req['controller'] %>#<%= req['action'] %> (<%= req['path'] %>.<%= req['format'] %>)</code></h4> | ||
<% if !req[:exception].empty? %> | ||
<h3><%= req['status'] %> Exception:</h3> | ||
<pre><%= req['exception'] %></pre> | ||
<%= render 'redis_log/param_table', params: req[:exception] %> | ||
<% end %> | ||
<% %w[Params Headers].each do |key| %> | ||
<h4><%= key %></h4> | ||
<% if req[key.downcase.to_sym].empty? %> | ||
(empty) | ||
<% else %> | ||
<%= render 'redis_log/param_table', heading: key, params: req[key.downcase.to_sym] %> | ||
<% end %> | ||
<% end %> | ||
<table> | ||
<tr> | ||
<td>Request ID</td> | ||
<td><code><%= req[:request_id] %></code></td> | ||
</tr> | ||
<tr> | ||
<td>Commit SHA</td> | ||
<td><code><%= req['sha'] %></code></td> | ||
</tr> | ||
</table> | ||
</li> | ||
</div> | ||
<% if wrapped %></div><% end %> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
<% impersonator_id ||= nil %> | ||
<% if impersonator_id.present? %> | ||
[<%= User.find(impersonator_id).username %> (impersonating <%= User.find(user_id).username %>)] | ||
<% elsif user_id.present? %> | ||
[<%= User.find(user_id).username %>] | ||
<% elsif session_id.nil? %> | ||
[NOSESS] | ||
<% else %> | ||
<img src="https://robohash.org/<%= session_id %>?size=20x20"> | ||
<% end %> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
<ul class="list-group" id='logs'> | ||
<% @requests.each do |req| %> | ||
<%= render 'row', req: req, wrapped: true %> | ||
<% end %> | ||
</ul> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
<h1>RedisLog#status</h1> | ||
<p>Find me in app/views/redis_log/status.html.erb</p> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
<h1>RedisLog#user</h1> | ||
<p>Find me in app/views/redis_log/user.html.erb</p> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
<ul class="list-group"> | ||
<% @sessions.each do |session| %> | ||
<% css_id = session[:id].gsub(/[^a-zA-Z0-9\-\_]/, '') %> | ||
<li class="list-group-item list-item-label" data-toggle="collapse" role="button" aria-expanded="false" aria-controls="<%= css_id %>" href="#<%= css_id %>"> | ||
<span class="badge"><%= session[:count] %></span> | ||
<%= render 'redis_log/user', session_id: session[:id], user_id: session[:user_id] %> | ||
<%= Time.at(session['start'].to_i).strftime("%-y/%-m/%-d %-H:%M") %> - <%= Time.at(session['end'].to_i).strftime("%-y/%-m/%-d %-H:%M") %> | ||
</li> | ||
<div class="collapse" style="margin-bottom:-1px" id="<%= css_id %>"> | ||
<ul class="list-group"> | ||
<% session[:requests].each do |req| %> | ||
<%= render 'redis_log/row', req: req %> | ||
<% end %> | ||
</ul> | ||
</div> | ||
<% end %> | ||
</ul> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
ActiveSupport::Notifications.subscribe "process_action.action_controller" do |name, started, finished, unique_id, data| | ||
request_id = data[:headers]["action_dispatch.request_id"] | ||
redis_log_id = data[:headers]["rack.session"]["redis_log_id"] | ||
redis_log_key = data[:headers]["redis_logs.log_key"] | ||
request_timestamp = data[:headers]["redis_logs.timestamp"] | ||
redis.zadd "requests/status/#{data[:status]}", request_timestamp, request_id | ||
redis.mapped_hmset redis_log_key, data.slice(:controller, :action, :format, :method, :status, :view_runtime, :db_runtime) | ||
if data[:exception].present? | ||
redis.hset redis_log_key, "exception", data[:exception].join("\n") | ||
ex = data[:exception_object] | ||
redis.mapped_hmset "#{redis_log_key}/exception", { | ||
file_name: ex.try(:file_name), | ||
annotated_source_code: ex.try(:annoted_source_code)&.join("\n"), | ||
line_number: ex.try(:line_number), | ||
backtrace: ex.try(:backtrace)&.join("\n"), | ||
message: ex.try(:message) | ||
} | ||
end | ||
RedisLogJob.perform_later(request_id, request_timestamp) | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
# frozen_string_literal: true | ||
|
||
CurrentCommit = (File.read('REVISION').strip if File.readable?('REVISION')) # rubocop:disable Style/ConstantName | ||
CurrentCommit = File.readable?('REVISION') ? File.read('REVISION').strip : `git rev-parse --short HEAD`.chomp # rubocop:disable Style/ConstantName |
Oops, something went wrong.