You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pulsar.apache.org by si...@apache.org on 2019/08/14 01:25:56 UTC
[pulsar] branch master updated: [dashboard] fix peek parse message
error (#4918)
This is an automated email from the ASF dual-hosted git repository.
sijie pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/pulsar.git
The following commit(s) were added to refs/heads/master by this push:
new a8b57c9 [dashboard] fix peek parse message error (#4918)
a8b57c9 is described below
commit a8b57c97c058862bce1c5b9d3435768d2071f09b
Author: Yi Tang <ss...@gmail.com>
AuthorDate: Wed Aug 14 09:25:50 2019 +0800
[dashboard] fix peek parse message error (#4918)
Fixes #4917
### Motivation
dashboard peek message api raise exception when format response cause treat all message as a JSON string
### Modifications
* format as JSON only if message is a JSON,
* otherwise if message is printable, return the original message,
* otherwise print hex like command with --hex option.
---
dashboard/Dockerfile | 2 +-
dashboard/django/stats/templates/stats/peek.html | 5 ++-
dashboard/django/stats/views.py | 47 ++++++++++++++++++++++--
3 files changed, 49 insertions(+), 5 deletions(-)
diff --git a/dashboard/Dockerfile b/dashboard/Dockerfile
index 01c84ea..6af19c4 100644
--- a/dashboard/Dockerfile
+++ b/dashboard/Dockerfile
@@ -25,7 +25,7 @@ RUN apt-get update
RUN apt-get -y install postgresql python sudo nginx supervisor
# Python dependencies
-RUN pip install uwsgi 'Django<2.0' psycopg2 pytz requests
+RUN pip install uwsgi 'Django<2.0' psycopg2 pytz requests hexdump
# Postgres configuration
COPY conf/postgresql.conf /etc/postgresql/9.6/main/
diff --git a/dashboard/django/stats/templates/stats/peek.html b/dashboard/django/stats/templates/stats/peek.html
index ebe4821..17d66b0 100644
--- a/dashboard/django/stats/templates/stats/peek.html
+++ b/dashboard/django/stats/templates/stats/peek.html
@@ -19,4 +19,7 @@
-->
-<pre id="output" class="autoscroll">{{ message_body }}</pre>
\ No newline at end of file
+<div id="output" class="autoscroll">
+ <pre>{{ message_type }}</pre>
+ <pre>{{ message_body }}</pre>
+</div>
diff --git a/dashboard/django/stats/views.py b/dashboard/django/stats/views.py
index b49994b..d0a7af4 100644
--- a/dashboard/django/stats/views.py
+++ b/dashboard/django/stats/views.py
@@ -18,12 +18,15 @@
#
import logging
+import struct
+
from django.shortcuts import render, get_object_or_404, redirect
from django.template import loader
from django.urls import reverse
from django.views import generic
from django.db.models import Q, IntegerField
from dashboard import settings
+import hexdump
import requests, json, re
from django.http import HttpResponseRedirect, HttpResponse
@@ -363,13 +366,51 @@ def messages(request, topic_name, subscription_name):
'subtitle' : subscription_name,
})
+
+def message_skip_meta(message_view):
+ if not message_view or len(message_view) < 4:
+ raise ValueError("invalid message")
+ meta_size = struct.unpack(">I", message_view[:4])
+ message_index = 4 + meta_size[0]
+ if len(message_view) < message_index:
+ raise ValueError("invalid message")
+ return message_view[message_index:]
+
+
+def get_message_from_http_response(response):
+ if response.status_code != 200:
+ return "ERROR", "status_code=%d" % response.status_code
+ message_view = memoryview(response.content)
+ if 'X-Pulsar-num-batch-message' in response.headers:
+ batch_size = int(response.headers['X-Pulsar-num-batch-message'])
+ if batch_size == 1:
+ message_view = message_skip_meta(message_view)
+ else:
+ # TODO: can not figure out multi-message batch for now
+ return "Batch(size=%d)" % batch_size, "<omitted>"
+
+ try:
+ text = str(message_view,
+ encoding=response.encoding or response.apparent_encoding,
+ errors='replace')
+ if not text.isprintable():
+ return "Hex", hexdump.hexdump(message_view, result='return')
+ except (LookupError, TypeError):
+ return "Hex", hexdump.hexdump(message_view, result='return')
+ try:
+ return "JSON", json.dumps(json.loads(text),
+ ensure_ascii=False, indent=4)
+ except json.JSONDecodeError:
+ return "Text", text
+
+
def peek(request, topic_name, subscription_name, message_number):
url = settings.SERVICE_URL + '/admin/v2/' + topic_name + '/subscription/' + subscription_name + '/position/' + message_number
response = requests.get(url)
- message = response.text
- message = message[message.index('{'):]
+ message_type, message = get_message_from_http_response(response)
context = {
- 'message_body' : json.dumps(json.loads(message), indent=4),
+ 'message_type': message_type,
+ 'message_body': message,
}
return render(request, 'stats/peek.html', context)