%link{:rel => 'stylesheet', :href => '/css/events.css'} %script{:src => '/js/typeahead.js'} %script{:src => '/js/md5.js'} #eventsController.row{'ng-controller' => 'eventsController'} -# last update time in corner %span#corner_status -# search box (and sort dropdown) #search.col-md-12.pull-right.main-content .panel #search_field.collapse.in{:role => 'search'} .panel-body %form.form-inline{:role => 'search'} #search_form_group.form-group.col-md-9 %input#search_input.form-control{:type => 'text', :placeholder => 'Search', 'ng-model' => 'search_field', 'search-typeahead' => ''} %small.help-block %a{'data-toggle' => 'modal', 'data-target' => '#howdoisearch'} How do I search? .form-group.col-md-2 %select#sort.form-control{'ng-model' => 'sort_field'} %option{disabled: true} Sort by %option{:value => 'client'} client %option{:value => '-client'} client (descending) %option{:value => 'check'} check %option{:value => '-check'} check (descending) %option{:value => 'status'} status %option{:value => '-status'} status (descending) %option{:value => 'age', :selected => 'selected'} age %option{:value => '-age'} age (descending) %option{:value => 'issued'} issued %option{:value => '-issued'} issued (descending) %option{:value => 'output'} output %option{:value => '-output'} output (descending) %input.btn.btn-success.pull-right{:type => 'submit', :value => 'Search', 'ng-click' => 'updateParams()'} -# left sidebar with stats #stats.col-md-3.pull-left.main-content .panel #stats_field.collapse.in{:role => 'stats'} .panel-body{'ng-hide' => 'events.length == 0 || events_spin'} -# stats by status #stats_status{'ng-hide' => 'events_spin'} #totals %span.label.label-warning.pointer{'ng-click' => 'appendQuery(1, "status", false)'}= ' - ' %span.label.label-danger.pointer{'ng-click' => 'appendQuery(2, "status", false)'}= ' - ' %span.label.label-info.pointer{'ng-click' => 'appendQuery(3, "status", false)'}= ' - ' -# stats by field #stats_by_count{'ng-repeat' => '(name, stat) in stats'} %h5 {{name | uppercase }} stats %table.table.table-striped{'ng-hide' => 'events_spin'} %tr %td {{name}} name %td Quantity %tr{'ng-repeat' => 's in stat | slice:0:10'} %td.col-md-3 %span.appendQuery{'ng-click' => 'appendQuery(s[0], name)'} {{s[0]}} %td.col-md-1.text-center {{s[1]}} -# all events #events.col-md-9.pull-right.main-content{:style => 'margin-bottom: 100px'} .panel #events_field.collapse.in{:role => 'events'} %ul.list-group -# events options .progress.progress-striped.active{'ng-show' => 'events_spin', :style => 'margin-top: 50px;'} .progress-bar.progress-bar-success{:role => 'progressbar', 'aria-valuenow' => '100', 'aria-valuemin' => '0', 'aria-valuemax' => '100', :style => 'width: 100%'} %span.sr-only getting events... .text-center{'ng-hide' => 'events.length || events_spin'} No Events .pull-right{'ng-hide' => 'events.length == 0 || events_spin'} %span.view View %select#limit{'ng-model' => 'limit_field'} %option{:value => '10'} 10 %option{:value => '20'} 20 %option{:value => '50', :selected => "selected"} 50 %option{:value => '100'} 100 %option{:value => '200'} 200 %a#events-accordian-toggle.text-right.pull-left{'ng-click' => 'bulkToggleDetails()', 'ng-hide' => 'events.length == 0 || events_spin'} {{bulk}} all details -# an event %br %li.list-group-item{'ng-repeat' => 'event in events'} .row .panel -# event header .panel-heading.flat-heading.event_line{:panel => '{{event.client.name}}/{{event.check.name}}'} .col-md-2 %h4 %span.label.pull-right.pointer{'class' => 'label-{{event.color}}', 'ng-click' => 'appendQuery(event.check.status, "status", false)'} {{event.wstatus}} %h5.event_title.pull-left %span.silenceBtn.glyphicon.glyphicon-volume-off{'ng-show' => 'event.client.silenced', 'ng-click' => 'updateSilenceDetails(event.client.silence_stash)', 'data-toggle' => 'modal', 'data-target' => '#silence_window_mini'} %span.appendQuery{'ng-click' => 'appendQuery(event.client.name, "client")'} {{event.client.name}} %span= ' / ' %span.silenceBtn.glyphicon.glyphicon-volume-off{'ng-show' => 'event.check.silenced', 'ng-click' => 'updateSilenceDetails(event.check.silence_stash)', 'data-toggle' => 'modal', 'data-target' => '#silence_window_mini'} %span.appendQuery{'ng-click' => 'appendQuery(event.check.name, "check")'} {{event.check.name}} %small.text-muted.muted-output \- {{event.check.output}} %h5 %span.glyphicon.glyphicon-collapse-down.toggleBtnIcon.pull-right{'ng-click' => 'toggleDetails(event.id)'} .panel-body.panel-collapse.collapse{:class => '{{event.showdetails}}', :id => '{{event.id}}'} -# event actions .dropdown.actions.pull-right %button.btn.btn-link.dropdown-toggle{'data-toggle' => 'dropdown'} Actions %span.caret %ul.dropdown-menu %li %a{:href => '#', 'ng-click' => 'resolveEvent(event.client.name, event.check.name)'} Resolve %li.divider %li.dropdown-header Silence %li %a{:href => '#', 'ng-click' => 'createSilenceDetails(event.client.name)', 'data-toggle' => 'modal', 'data-target' => '#silence_window'} Client %li %a{:href => '#', 'ng-click' => 'createSilenceDetails(event.client.name, event.check.name)', 'data-toggle' => 'modal', 'data-target' => '#silence_window'} Check -# event attributes %dl.dl-horizontal.col-md-5.pull-left %dt.attr_title{'ng-repeat-start' => 'attr in event.attributes.left'} {{attr[0]}} %dd.attr_value{'ng-repeat-end' => '', 'ng-bind-html' => 'attr[1]'} %dl.dl-horizontal.col-md-5.pull-left %dt.attr_title{'ng-repeat-start' => 'attr in event.attributes.right'} {{attr[0]}} %dd.attr_value{'ng-repeat-end' => '', 'ng-bind-html' => 'attr[1]'} -# event output .col-md-12.pull-left.output {{event.check.output}} -# mini silence dialog (for seeing existing silences) #silence_window_mini.silence_window.modal.fade .modal-dialog .modal-content .modal-header Silence Details for {{silencePath}} %button.btn.btn-link.btn-xs.pull-right.close_popover{:type => 'button', 'data-dismiss' => 'modal'} %span.glyphicon.glyphicon-remove close .modal-body %dl.dl-horizontal %dt{'ng-show' => 'silenceCreated'} Created %dd{'ng-show' => 'silenceCreated'} {{silenceCreated}} %dt{'ng-show' => 'silenceOwner'} Owner %dd{'ng-show' => 'silenceOwner'} {{silenceOwner}} %dt{:class => 'text-{{silenceExpirationClass}}', 'ng-show' => 'silenceExpires'} Expires %dd{:class => 'text-{{silenceExpirationClass}}', 'ng-show' => 'silenceExpires'} {{silenceExpires}} %dt{'ng-show' => 'silenceReason'} Reason %dd{'ng-show' => 'silenceReason'} {{silenceReason}} .modal-footer %button.deleteSilenceBtn.btn.btn-danger.btn-sm.pull-right{:type => 'button', 'ng-click' => "deleteSilence('{{silencePath}}')"} %span.glyphicon.glyphicon-remove Delete -# regular silence dialog (for creating a new silence) #silence_window.modal.fade .modal-dialog .modal-content .modal-header %button.close.pull-right{:type => 'button', 'data-dismiss' => 'modal', 'aria-hidden' => 'true'} %h4.modal-title Silence {{silencePath}} .modal-body %form#silence_form.form-horizontal{:role => 'form'} .form-group.silence_owner.has-feedback %label.col-sm-2.control-label{:for => 'owner'} Owner* .col-sm-10 %input#owner.form-control{:type => 'text', :placeholder => 'Joe Smith'} .form-group.silence_reason.has-feedback %label.col-sm-2.control-label{:for => 'reason'} Reason* .col-sm-10 %textarea#reason.form-control{:placeholder => 'Enter reason here', :rows => '3'} .form-group %label.col-sm-2.control-label{:for => 'expires'} Expiration* .col-sm-10 .radio %label %input#resolve{:type => 'radio', :name => 'expiration', :value => 'resolve', :checked => ''} On resolve %span.glyphicon.glyphicon-question-sign{'data-toggle' => 'tooltip', 'data-placement' => 'right', :title => '"On resolve" will cause this silence to be deleted once the check clears for check, clients require all checks to clear. A minimum of 1 hour is enforced.'} .radio %label %input#timer{:type => 'radio', :name => 'expiration', :value => 'timer'} %span.pull-left Timer .col-sm-3.silence_timer_val.has-feedback %input#timer_val.input-sm.form-control{:type => 'text', :name => 'expirationl', :placeholder => ''} %span.glyphicon.glyphicon-question-sign{'data-toggle' => 'tooltip', 'data-placement' => 'right', :title => '"Timer" will cause this silence to be deleted in a predetermined time span. The expires value should be inputted as a number followed by a single character. m = minutes, h = hours, d = days, w = weeks. (examples 15m, 2h, 1d, 5w)'} .radio %label %input#never{:type => 'radio', :name => 'expiration', :value => 'never'} Never %span.glyphicon.glyphicon-question-sign{'data-toggle' => 'tooltip', 'data-placement' => 'right', :title => '"Never" will cause this silence to, surprise surprise, never expire. It will remain silence until yourself or someone else manually deletes the silence. It is highly discourage to permanently silence anything. Its extremely rare that that is ever the correct action.'} .modal-footer %button.btn.btn-default.pull-right{:type => 'submit', 'ng-click' => 'saveSilence()'} Create -# help dialog #howdoisearch.modal.fade .modal-dialog .modal-content .modal-header %button.close{:type => 'button', 'data-dismiss' => 'modal', 'aria-hidden' => 'true'} %h4.modal-title How Do I Search? .modal-body %h4 Available Fields %p.well.well-sm {{event_fields_name | joinBy : ', '}} %h4 Query Syntax %h5 Examples %table.table.table-striped %tr %td Desired Result %td Query %tr %td For clients STARTING with "web" %td client:web* %tr %td For checks ENDING with "process" %td check:process %tr %td For checks MATCHING with "disk_usage" %td check:"disk_usage" %tr %td For statuses warning or critical %td status:[1 TO 2] %tr %td For "web" clients and critical %td client:web* AND status:2 %tr %td Search for everything, except checks that start with "disk" %td *:* AND NOT check:disk* %tr %td For "web" or "dbs" clients and status is unknown %td client:(web* OR db*) AND status:3 %tr %td Full text search for "failure" %td failure %tr %td Events since Jan 1, 2014 %td issued:[1388534400 TO Infinity] %p The Cloudant search query syntax is based on the %a{:href => 'http://lucene.apache.org/core/4_2_1/queryparser/org/apache/lucene/queryparser/classic/package-summary.html#package_description'} Lucene syntax. Search queries take the form of "name:value" (unless the name is omitted, in which case they hit the default field). %p Queries over multiple fields can be logically combined and groups and fields can be grouped. The available logical operators are: "AND", "+", "OR", "NOT" and "-", and are case sensitive. Range queries can run over strings or numbers. %p If you want a fuzzy search you can run a query with "~" to find terms like the search term, for instance "look~" will find terms book and took. %p You can also increase the importance of a search term by using the boost character "^". This makes matches containing the term more relevant, e.g. cloudant "data layer"^4 will make results containing "data layer" 4 times more relevant. The default boost value is 1. Boost values must be positive, but can be less than 1 (e.g. 0.5 to reduce importance). %p Wild card searches are supported, for both single ("?") and multiple ("*") character searches. "dat?" would match date and data, "dat*" would match date, data, database, dates etc. Wildcards must come after a search term, you cannot do a query like "*base". %p The following characters require escaping if you want to search on them %p.well.well-sm + - && || ! ( ) { } [ ] ^ " ~ * ? : \ / .modal-footer %button.btn.btn-default{:type => 'button', 'data-dismiss' => 'modal'} Close