mirror of
https://github.com/codeninjasllc/discourse.git
synced 2025-03-14 00:50:14 -04:00
Merge pull request #4017 from tgxworld/add_admin_banner_for_logster
FEATURE: Admin Banner when Logster logs is getting flooded.
This commit is contained in:
commit
f32f0d6337
7 changed files with 148 additions and 2 deletions
|
@ -1,4 +1,7 @@
|
|||
import { on } from 'ember-addons/ember-computed-decorators';
|
||||
import StringBuffer from 'discourse/mixins/string-buffer';
|
||||
import { iconHTML } from 'discourse/helpers/fa-icon';
|
||||
import LogsNotice from 'discourse/services/logs-notice';
|
||||
|
||||
export default Ember.Component.extend(StringBuffer, {
|
||||
rerenderTriggers: ['site.isReadOnly'],
|
||||
|
@ -18,8 +21,33 @@ export default Ember.Component.extend(StringBuffer, {
|
|||
notices.push([this.siteSettings.global_notice, 'alert-global-notice']);
|
||||
}
|
||||
|
||||
if (notices.length > 0) {
|
||||
buffer.push(_.map(notices, n => "<div class='row'><div class='alert alert-info " + n[1] + "'>" + n[0] + "</div></div>").join(""));
|
||||
if (!LogsNotice.currentProp('hidden')) {
|
||||
notices.push([LogsNotice.currentProp('message'), 'alert-logs-notice', `<div class='close'>${iconHTML('times')}</div>`]);
|
||||
}
|
||||
|
||||
if (notices.length > 0) {
|
||||
buffer.push(_.map(notices, n => {
|
||||
var html = `<div class='row'><div class='alert alert-info ${n[1]}'>${n[0]}`;
|
||||
if (n[2]) html += n[2];
|
||||
html += '</div></div>';
|
||||
return html;
|
||||
}).join(""));
|
||||
}
|
||||
},
|
||||
|
||||
@on('didInsertElement')
|
||||
_setupLogsNotice() {
|
||||
LogsNotice.current().addObserver('hidden', () => {
|
||||
this.rerenderString();
|
||||
});
|
||||
|
||||
this.$().on('click.global-notice', '.alert-logs-notice .close', () => {
|
||||
LogsNotice.currentProp('text', '');
|
||||
});
|
||||
},
|
||||
|
||||
@on('willDestroyElement')
|
||||
_teardownLogsNotice() {
|
||||
this.$().off('click.global-notice');
|
||||
}
|
||||
});
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
import LogsNotice from 'discourse/services/logs-notice';
|
||||
import Singleton from 'discourse/mixins/singleton';
|
||||
|
||||
export default {
|
||||
name: "logs-notice",
|
||||
after: "message-bus",
|
||||
|
||||
initialize: function (container) {
|
||||
const siteSettings = container.lookup('site-settings:main');
|
||||
const messageBus = container.lookup('message-bus:main');
|
||||
const keyValueStore = container.lookup('key-value-store:main');
|
||||
LogsNotice.reopenClass(Singleton, {
|
||||
createCurrent() {
|
||||
return this.create({ messageBus, keyValueStore, siteSettings});
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
69
app/assets/javascripts/discourse/services/logs-notice.js.es6
Normal file
69
app/assets/javascripts/discourse/services/logs-notice.js.es6
Normal file
|
@ -0,0 +1,69 @@
|
|||
import { on, observes } from 'ember-addons/ember-computed-decorators';
|
||||
import computed from 'ember-addons/ember-computed-decorators';
|
||||
|
||||
const LOGS_NOTICE_KEY = "logs-notice-text";
|
||||
|
||||
const LogsNotice = Ember.Object.extend({
|
||||
text: "",
|
||||
|
||||
@on('init')
|
||||
_setup() {
|
||||
if (!this.get('isActivated')) return;
|
||||
|
||||
const text = this.keyValueStore.getItem(LOGS_NOTICE_KEY);
|
||||
if (text) this.set('text', text);
|
||||
|
||||
this.messageBus.subscribe("/logs_error_rate_exceeded", data => {
|
||||
const duration = data.duration;
|
||||
var siteSettingLimit = 0;
|
||||
|
||||
if (duration === 'minute') {
|
||||
siteSettingLimit = this.siteSettings.alert_admins_if_errors_per_minute;
|
||||
} else if (duration === 'hour') {
|
||||
siteSettingLimit = this.siteSettings.alert_admins_if_errors_per_hour;
|
||||
}
|
||||
|
||||
this.set('text',
|
||||
I18n.t('logs_error_rate_exceeded_notice', {
|
||||
timestamp: moment().format("YYYY-MM-DD H:mm:ss"),
|
||||
siteSettingLimit: siteSettingLimit,
|
||||
rate: data.rate,
|
||||
duration: duration,
|
||||
url: Discourse.getURL('/logs')
|
||||
})
|
||||
);
|
||||
});
|
||||
},
|
||||
|
||||
@computed('text')
|
||||
isEmpty(text) {
|
||||
return Ember.isEmpty(text);
|
||||
},
|
||||
|
||||
@computed('text')
|
||||
message(text) {
|
||||
return new Handlebars.SafeString(text);
|
||||
},
|
||||
|
||||
@computed('currentUser')
|
||||
isAdmin(currentUser) {
|
||||
return currentUser && currentUser.admin;
|
||||
},
|
||||
|
||||
@computed('isEmpty', 'isAdmin')
|
||||
hidden(isEmpty, isAdmin) {
|
||||
return !isAdmin || isEmpty;
|
||||
},
|
||||
|
||||
@observes('text')
|
||||
_updateKeyValueStore() {
|
||||
this.keyValueStore.setItem(LOGS_NOTICE_KEY, this.get('text'));
|
||||
},
|
||||
|
||||
@computed('siteSettings.alert_admins_if_errors_per_hour', 'siteSettings.alert_admins_if_errors_per_minute')
|
||||
isActivated(errorsPerHour, errorsPerMinute) {
|
||||
return errorsPerHour > 0 || errorsPerMinute > 0;
|
||||
}
|
||||
});
|
||||
|
||||
export default LogsNotice;
|
|
@ -56,3 +56,22 @@ Logster.config.current_context = lambda{|env,&blk|
|
|||
Logster.config.subdirectory = "#{GlobalSetting.relative_url_root}/logs"
|
||||
|
||||
Logster.config.application_version = Discourse.git_version
|
||||
|
||||
redis = Logster.store.redis
|
||||
Logster.config.redis_prefix = "#{redis.namespace}"
|
||||
Logster.config.redis_raw_connection = redis.without_namespace
|
||||
|
||||
%w{minute hour}.each do |duration|
|
||||
site_setting_error_rate = SiteSetting.public_send("alert_admins_if_errors_per_#{duration}")
|
||||
|
||||
if site_setting_error_rate > 0
|
||||
Logster.store.public_send(
|
||||
"register_rate_limit_per_#{duration}",
|
||||
[Logger::WARN, Logger::ERROR, Logger::FATAL, Logger::UNKNOWN],
|
||||
site_setting_error_rate
|
||||
) do |rate|
|
||||
|
||||
MessageBus.publish("/logs_error_rate_exceeded", { rate: rate, duration: duration })
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -786,6 +786,7 @@ en:
|
|||
too_few_topics_and_posts_notice: "Let's <a href='http://blog.discourse.org/2014/08/building-a-discourse-community/'>get this discussion started!</a> There are currently <strong>%{currentTopics} / %{requiredTopics}</strong> topics and <strong>%{currentPosts} / %{requiredPosts}</strong> posts. New visitors need some conversations to read and respond to."
|
||||
too_few_topics_notice: "Let's <a href='http://blog.discourse.org/2014/08/building-a-discourse-community/'>get this discussion started!</a> There are currently <strong>%{currentTopics} / %{requiredTopics}</strong> topics. New visitors need some conversations to read and respond to."
|
||||
too_few_posts_notice: "Let's <a href='http://blog.discourse.org/2014/08/building-a-discourse-community/'>get this discussion started!</a> There are currently <strong>%{currentPosts} / %{requiredPosts}</strong> posts. New visitors need some conversations to read and respond to."
|
||||
logs_error_rate_exceeded_notice: "%{timestamp}: Current rate of <a href='%{url}' target='_blank'>%{rate} errors/%{duration}</a> has exceeded site settings's limit of %{siteSettingLimit} errors/%{duration}."
|
||||
|
||||
learn_more: "learn more..."
|
||||
|
||||
|
|
|
@ -981,6 +981,9 @@ en:
|
|||
max_invites_per_day: "Maximum number of invites a user can send per day."
|
||||
max_topic_invitations_per_day: "Maximum number of topic invitations a user can send per day."
|
||||
|
||||
alert_admins_if_errors_per_minute: "Number of errors per minute in order to trigger an admin alert. A value of 0 disables this feature. NOTE: requires restart."
|
||||
alert_admins_if_errors_per_hour: "Number of errors per hour in order to trigger an admin alert. A value of 0 disables this feature. NOTE: requires restart."
|
||||
|
||||
suggested_topics: "Number of suggested topics shown at the bottom of a topic."
|
||||
limit_suggested_to_category: "Only show topics from the current category in suggested topics."
|
||||
|
||||
|
|
|
@ -765,6 +765,14 @@ rate_limits:
|
|||
tl2_additional_likes_per_day_multiplier: 1.5
|
||||
tl3_additional_likes_per_day_multiplier: 2
|
||||
tl4_additional_likes_per_day_multiplier: 3
|
||||
alert_admins_if_errors_per_minute:
|
||||
client: true
|
||||
shadowed_by_global: true
|
||||
default: 0
|
||||
alert_admins_if_errors_per_hour:
|
||||
client: true
|
||||
shadowed_by_global: true
|
||||
default: 0
|
||||
|
||||
developer:
|
||||
force_hostname:
|
||||
|
|
Loading…
Reference in a new issue