-
Notifications
You must be signed in to change notification settings - Fork 210
/
subscription.html
324 lines (296 loc) · 18.3 KB
/
subscription.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
<section ng-controller="SubscriptionController">
<ol class="breadcrumb">
<li><a href="#/">home</a></li>
<li><a href="#/groups">groups</a></li>
<li><a ng-href="#/groups/{{groupName}}">{{groupName}}</a></li>
<li><a ng-href="#/groups/{{groupName}}/topics/{{topicName}}">{{topicName}}</a></li>
<li class="active">{{subscriptionName}}</li>
</ol>
<div class="pull-right">
<button ng-show="subscription.state === 'ACTIVE'" class="btn btn-warning" ng-click="suspend()">Suspend</button>
<button ng-show="subscription.state === 'SUSPENDED'" class="btn btn-success" ng-click="activate()">Activate</button>
<button class="btn btn-primary" ng-click="edit()">Edit</button>
<button class="btn btn-primary" ng-click="clone()">Clone</button>
<button class="btn btn-danger" ng-click="remove()">Remove</button>
</div>
<h2><small>Subscription:</small> {{subscription.name}}</h2>
<h3><small>Endpoint:</small> {{subscription.endpoint}}</h3>
<h3><small>Owner ({{subscription.owner.source}}):</small> <owner-name owner="subscription.owner"/></h3>
<p class="lead">{{subscription.description}}</p>
<div class="row text-center">
<div class="col-md-12">
<p class="alert {{subscription.state === 'ACTIVE' ? 'alert-success' : 'alert-danger'}}">
{{subscription.state}}
</p>
</div>
</div>
<div class="row" ng-show="health.status === 'UNHEALTHY'">
<div class="col-md-12">
<div class="panel panel-danger">
<div class="panel-heading">
<h3 class="panel-title">Subscription health problems</h3>
</div>
<div class="panel-body">
<p ng-show="health.problems.lagging">
<b>Subscription lag is growing</b>. Examine output rate and service response codes, looks like it is
not consuming at full speed.
</p>
<p ng-show="health.problems.malfunctioning">
<b>Consuming service returns a lot of 5xx codes</b>. Looks like it might be malfunctioning or doesn't know
how to handle messages. Take a look at "Last undelivered message" for more information.
</p>
<p ng-show="health.problems.receivingMalformedMessages">
<b>Consuming service returns a lot of 4xx codes</b>. Maybe you are receiving some malformed messages?
If this is normal behavior, switch <b>Retry on 4xx status</b> flag to false. This way Hermes will
not try to resend malformed messages, reducing traffic.
</p>
<p ng-show="health.problems.timingOut">
<b>Consuming service times out a lot</b>. Hermes times out after 1 second, if you are not able to process
message during this time, connection is reset and delivery fails.
</p>
<p ng-show="health.problems.unreachable">
<b>Unable to connect to consuming service instances</b>. It is either network issue or your service instance
is down.
</p>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="panel panel-info">
<div class="panel-heading">
<h3 class="panel-title">Subscription metrics</h3>
</div>
<div class="panel-body">
<p><strong><a ng-href="{{metricsUrls.rate}}">Delivery rate:</a></strong> {{metrics.rate | number:2}}</p>
<p>
<strong><a ng-href="{{metricsUrls.latency}}">Subscriber latency</a></strong>
<span uib-popover='Latency of acknowledging messages by subscribing service as measured by Hermes.' popover-trigger="mouseenter" class="fa helpme pull-right"></span>
</p>
<p><strong><a ng-href="{{metricsUrls.delivered}}">Delivered:</a></strong> {{metrics.delivered}}</p>
<p><strong><a ng-href="{{metricsUrls.discarded}}">Discarded:</a></strong> {{metrics.discarded}}</p>
<p>
<strong><a ng-href="{{metricsUrls.lag}}">Lag:</a></strong> {{metrics.lag}}
<span uib-popover='Total number of events waiting to be delivered. Each subscription has a "natural" lag, which depends on production rate.' popover-trigger="mouseenter" class="fa helpme pull-right"></span>
</p>
<p>
<strong><a ng-href="{{metricsUrls.outputRate}}">Output rate</a></strong>
<span uib-popover='Maximum sending rate calculated based on receiving service performance. For well-performing service output rate should be equal to rate limit.' popover-trigger="mouseenter" class="fa helpme pull-right"></span>
</p>
</div>
</div>
<div class="panel panel-info">
<div class="panel-heading">
<h3 class="panel-title">Service response metrics</h3>
</div>
<div class="panel-body">
<p><strong><a ng-href="{{metricsUrls['2xx']}}">2xx</a></strong></p>
<p><strong><a ng-href="{{metricsUrls['4xx']}}">4xx</a></strong></p>
<p><strong><a ng-href="{{metricsUrls['5xx']}}">5xx</a></strong></p>
<p><strong><a ng-href="{{metricsUrls.timeouts}}">Network timeouts</a></strong></p>
<p><strong><a ng-href="{{metricsUrls.networkErrors}}">Other network errors</a></strong></p>
</div>
</div>
</div>
<div class="col-md-6">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Properties</h3>
</div>
<div class="panel-body">
<p>
<strong>Content type:</strong> {{subscription.contentType}}
</p>
<p>
<strong>Delivery type:</strong> {{subscription.deliveryType}}
<span uib-popover='Hermes can deliver messages in SERIAL (one message at a time) or in BATCH (group of messages at a time).' popover-trigger="mouseenter" class="fa helpme pull-right"></span>
</p>
<p>
<strong>Mode:</strong> {{subscription.mode}}
<span uib-popover='Hermes can deliver messages in ANYCAST (to one of subscribed hosts) or in BROADCAST (to all subscribed hosts) mode.' popover-trigger="mouseenter" class="fa helpme pull-right"></span>
</p>
<p ng-show="subscription.deliveryType === 'SERIAL'">
<strong>Rate limit:</strong> {{subscription.subscriptionPolicy.rate}}
<span uib-popover='Maximum rate defined by user (per data center). Maximum rate calculated by algorithm can be observed in "Output rate" metric.' popover-trigger="mouseenter" class="fa helpme pull-right"></span>
</p>
<p ng-show="subscription.deliveryType === 'BATCH'">
<strong>Batch size:</strong> {{subscription.subscriptionPolicy.batchSize}} messages
<span uib-popover='Desired number of messages in a single batch.' popover-trigger="mouseenter" class="fa helpme pull-right"></span>
</p>
<p ng-show="subscription.deliveryType === 'BATCH'">
<strong>Batch time window:</strong> {{subscription.subscriptionPolicy.batchTime}} milliseconds
<span uib-popover='Max time between arrival of first message to batch delivery attempt.' popover-trigger="mouseenter" class="fa helpme pull-right"></span>
</p>
<p ng-show="subscription.deliveryType === 'BATCH'">
<strong>Batch volume:</strong> {{subscription.subscriptionPolicy.batchVolume}} bytes
<span uib-popover='Desired number of bytes in single batch.' popover-trigger="mouseenter" class="fa helpme pull-right"></span>
</p>
<p ng-show="subscription.deliveryType === 'BATCH'">
<strong>Request timeout:</strong> {{subscription.subscriptionPolicy.requestTimeout}} milliseconds
<span uib-popover='Max time for processing message by subscriber.' popover-trigger="mouseenter" class="fa helpme pull-right"></span>
</p>
<p ng-show="subscription.deliveryType === 'SERIAL'">
<strong>Sending delay:</strong> {{subscription.subscriptionPolicy.sendingDelay}} milliseconds
<span uib-popover='Amount of time in ms after which an event will be send. Useful if events from two topics are sent at the same time and you want to increase chance that events from one topic will be deliver after events from other topic.' popover-trigger="mouseenter" class="fa helpme pull-right"></span>
</p>
<p>
<strong>Message TTL:</strong> {{subscription.subscriptionPolicy.messageTtl}} seconds
<span uib-popover='Amount of time a message can be held in sending queue and retried. If message will not be delivered during this time, it will be discarded.' popover-trigger="mouseenter" class="fa helpme pull-right"></span>
</p>
<p><strong>Message delivery tracking:</strong> {{ trackingModeName[subscription.trackingMode] }}</p>
<p>
<strong>Retry on 4xx status:</strong> {{subscription.subscriptionPolicy.retryClientErrors}}
<span uib-popover='If false, message will not be retried when service responds with 4xx status (i.e. Bad Request).' popover-trigger="mouseenter" class="fa helpme pull-right"></span>
</p>
<p>
<strong>Retry backoff:</strong> {{subscription.subscriptionPolicy.messageBackoff}} milliseconds
<span uib-popover='Minimum amount of time between consecutive message retries.' popover-trigger="mouseenter" class="fa helpme pull-right"></span>
</p>
<p>
<strong>Monitoring severity:</strong> {{subscription.monitoringDetails.severity}}
<span uib-popover="How important should be the subscription's health for the monitoring." popover-trigger="mouseenter" class="fa helpme pull-right"></span>
</p>
<p>
<strong>Monitoring reaction:</strong> {{subscription.monitoringDetails.reaction}}
<span uib-popover='Information for monitoring how to react when the subscription becomes unhealthy (e.g. team name or Pager Duty ID).' popover-trigger="mouseenter" class="fa helpme pull-right"></span>
</p>
<p>
<strong>Deliver using http/2:</strong> {{subscription.http2Enabled}}
<span uib-popover='If true hermes will deliver messages using http/2 protocol.' popover-trigger="mouseenter" class="fa helpme pull-right"></span>
</p>
<p ng-repeat="(key, entry) in endpointAddressResolverMetadataConfig">
<strong>{{entry.title}}:</strong>
{{entry.options[subscription.endpointAddressResolverMetadata[key]] || subscription.endpointAddressResolverMetadata[key]}}
<span ng-show="entry.hint" uib-popover="{{entry.hint}}" popover-trigger="mouseenter" class="fa helpme pull-right"></span>
</p>
<p ng-repeat="(key, value) in notSupportedEndpointAddressResolverMetadataEntries(subscription.endpointAddressResolverMetadata)">
<strong>{{key}}:</strong> {{value}}
</p>
</div>
</div>
<div class="panel panel-danger">
<div class="panel-heading">
<h3 class="panel-title">Messages retransmission</h3>
</div>
<div class="panel-body">
<form class="form-inline">
<div class="form-group">
<div class="input-group">
<input class="form-control" style="width: 250px" type="input" readonly placeholder="since..." id="retransmitFromDate"/>
<span class="input-group-btn">
<button class="btn btn-default" type="button" id="retransmitCalendarButton"><span class="glyphicon glyphicon-time"></span></button>
</span>
</div>
<button class="btn btn-danger" ng-click="retransmit()"></span> Retransmit</button>
<span class="loading-in-panel" ng-show="retransmissionLoading">
<i class=" fa fa-circle-o-notch fa-spin fa-2x"></i>
</span>
</div>
</form>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6" ng-show="lastUndelivered.message">
<div class="panel panel-warning">
<div class="panel-heading">
<h3 class="panel-title">Last undelivered message</h3>
</div>
<div class="panel-body">
<p><strong>Time:</strong> {{lastUndelivered.timestamp | date:'yyyy-MM-dd HH:mm:ss'}}</p>
<p><strong>Reason:</strong> {{lastUndelivered.reason}}</p>
<p>
<strong>Message:</strong>
<pre class="pre-scrollable">
{{lastUndelivered.message}}
</pre>
</p>
</div>
</div>
</div>
<div class="col-md-6" ng-show="subscription.trackingEnabled">
<div class="panel panel-info">
<div class="panel-heading">
<h3 class="panel-title">Show event trace</h3>
</div>
<div class="panel-body">
<form class="form-inline">
<div class="form-group">
<input class="form-control" style="width: 350px" type="input" id="eventId" name="eventId" placeholder="event id: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" ng-model="eventId"/>
<button class="btn btn-primary" ng-click="showTrace()"><span class="glyphicon glyphicon-search" aria-hidden="true"></span></button>
</div>
</form>
<h5> </h5>
<table class="table" ng-show="eventTrace.length > 0">
<th>Phase</th>
<th>Time</th>
<th>Status</th>
<tbody>
<tr ng-repeat="trace in eventTrace">
<td>{{trace.subscription ? 'SENDING' : 'RECEIVING'}}</td>
<td>{{trace.timestamp | date:'yyyy-MM-dd HH:mm:ss.sss'}}</td>
<td>{{trace.status}} {{trace.status != 'SUCCESS' ? trace.reason : ''}}</td>
</tr>
</tbody>
</table>
<p ng-show="eventTrace.length == 0 && eventId">No matches found - is the id correct? Remember we keep traces for 14 days.</p>
</div>
</div>
</div>
</div>
<div class="row" ng-show="subscription.filters.length > 0">
<div class="col-md-12" ng-show="subscription.filters">
<div class="panel">
<div class="panel-heading">
<h3 class="panel-title">Subscription filters</h3>
</div>
<table class="table">
<tr>
<th>#</th>
<th>Type</th>
<th>Path</th>
<th>Matcher</th>
<th> </th>
</tr>
<tr ng-repeat="filter in subscription.filters">
<td>{{$index + 1}}</td>
<td>{{filter.type}}</td>
<td>{{filter.path}}</td>
<td>{{filter.matcher}}</td>
</tr>
</table>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12" ng-show="undelivered">
<div class="panel panel-danger">
<div class="panel-heading">
<h3 class="panel-title">Last 100 undelivered messages</h3>
</div>
<table class="table">
<tr>
<th>#</th>
<th>MessageId</th>
<th>Status</th>
<th>Reason</th>
<th>Timestamp</th>
<th> </th>
</tr>
<tr ng-repeat="msglog in undelivered">
<td>{{$index + 1}}</td>
<td>{{msglog.messageId}}</td>
<td>{{msglog.status}}</td>
<td>{{msglog.reason}}</td>
<td>{{msglog.timestamp | date:'yyyy-MM-dd HH:mm:ss'}}</td>
<td><button type="button" class="btn-xs btn-primary" ng-show="msglog.isPreviewable()"
ng-click="previewMessage(msglog.cluster, msglog.partition, msglog.offset, msglog.messageId)">
<span class="glyphicon glyphicon-search"></span></button></td>
</tr>
</table>
</div>
</div>
</div>
</section>