Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 52 additions & 25 deletions storm-core/src/clj/org/apache/storm/daemon/logviewer.clj
Original file line number Diff line number Diff line change
Expand Up @@ -538,13 +538,31 @@
(int (/ (alength needle) -2)))) ;; Addition
:length default-bytes-per-page})))

(defn url-to-match-centered-in-log-page-daemon-file
[needle fname offset port]
(let [host (Utils/localHostname)
port (logviewer-port)
fname (clojure.string/join Utils/FILE_PATH_SEPARATOR (take-last 1 (split fname (re-pattern Utils/FILE_PATH_SEPARATOR))))]
(url (str "http://" host ":" port "/daemonlog")
{:file fname
:start (max 0
(- offset
(int (/ default-bytes-per-page 2))
(int (/ (alength needle) -2)))) ;; Addition
:length default-bytes-per-page})))

(defnk mk-match-data
[^bytes needle ^ByteBuffer haystack haystack-offset file-offset fname
:before-bytes nil :after-bytes nil]
(let [url (url-to-match-centered-in-log-page needle
fname
file-offset
(*STORM-CONF* LOGVIEWER-PORT))
:is-daemon false :before-bytes nil :after-bytes nil]
(let [url (if is-daemon
(url-to-match-centered-in-log-page-daemon-file needle
fname
file-offset
(*STORM-CONF* LOGVIEWER-PORT))
(url-to-match-centered-in-log-page needle
fname
file-offset
(*STORM-CONF* LOGVIEWER-PORT)))
haystack-bytes (.array haystack)
before-string (if (>= haystack-offset grep-context-size)
(String. haystack-bytes
Expand Down Expand Up @@ -640,7 +658,7 @@
"As the file is read into a buffer, 1/2 the buffer's size at a time, we
search the buffer for matches of the substring and return a list of zero or
more matches."
[file file-len offset-to-buf init-buf-offset stream bytes-skipped
[is-daemon file file-len offset-to-buf init-buf-offset stream bytes-skipped
bytes-read ^ByteBuffer haystack ^bytes needle initial-matches num-matches
^bytes before-bytes]
(loop [buf-offset init-buf-offset
Expand All @@ -665,6 +683,7 @@
offset
file-offset
(.getCanonicalPath file)
:is-daemon is-daemon
:before-bytes before-arg
:after-bytes after-arg))))
(let [before-str-to-offset (min (.limit haystack)
Expand Down Expand Up @@ -721,7 +740,7 @@
context lines. Other information is included to be useful for progressively
searching through a file for display in a UI. The search string must
grep-max-search-size bytes or fewer when decoded with UTF-8."
[file ^String search-string :num-matches 10 :start-byte-offset 0]
[file ^String search-string :is-daemon false :num-matches 10 :start-byte-offset 0]
{:pre [(not (empty? search-string))
(<= (count (.getBytes search-string "UTF-8")) grep-max-search-size)]}
(let [zip-file? (.endsWith (.getName file) ".gz")
Expand Down Expand Up @@ -756,7 +775,9 @@
byte-offset start-byte-offset
before-bytes nil]
(let [[matches new-byte-offset new-before-bytes]
(buffer-substring-search! file
(buffer-substring-search!
is-daemon
file
file-len
byte-offset
init-buf-offset
Expand All @@ -783,16 +804,17 @@
new-buf-offset
new-byte-offset
new-before-bytes))
(mk-grep-response search-bytes
start-byte-offset
matches
(if-not (and (< (count matches) num-matches)
(>= @total-bytes-read file-len))
(let [next-byte-offset (+ (get (last matches)
"byteOffset")
(alength search-bytes))]
(if (> file-len next-byte-offset)
next-byte-offset)))))))))
(merge {"isDaemon" (if is-daemon "yes" "no")}
(mk-grep-response search-bytes
start-byte-offset
matches
(if-not (and (< (count matches) num-matches)
(>= @total-bytes-read file-len))
(let [next-byte-offset (+ (get (last matches)
"byteOffset")
(alength search-bytes))]
(if (> file-len next-byte-offset)
next-byte-offset))))))))))

(defn- try-parse-int-param
[nam value]
Expand All @@ -805,7 +827,7 @@
throw))))

(defn search-log-file
[fname user ^String root-dir search num-matches offset callback origin]
[fname user ^String root-dir is-daemon search num-matches offset callback origin]
(let [file (.getCanonicalFile (File. root-dir fname))]
(if (.exists file)
(if (or (blank? (*STORM-CONF* UI-FILTER))
Expand All @@ -819,10 +841,13 @@
(if (and (not (empty? search))
<= (count (.getBytes search "UTF-8")) grep-max-search-size)
(json-response
(substring-search file
search
:num-matches num-matches-int
:start-byte-offset offset-int)
(merge {"isDaemon" (if is-daemon "yes" "no")}
(substring-search file
search
:is-daemon is-daemon
:num-matches num-matches-int
:start-byte-offset offset-int))

callback
:headers {"Access-Control-Allow-Origin" origin
"Access-Control-Allow-Credentials" "true"})
Expand Down Expand Up @@ -1090,10 +1115,12 @@
;; :keys list, or this rule could stop working when an authentication
;; filter is configured.
(try
(let [user (.getUserName http-creds-handler servlet-request)]
(let [user (.getUserName http-creds-handler servlet-request)
is-daemon (= (:is-daemon m) "yes")]
(search-log-file (URLDecoder/decode file)
user
(if (= (:is-daemon m) "yes") daemonlog-root log-root)
(if is-daemon daemonlog-root log-root)
is-daemon
(:search-string m)
(:num-matches m)
(:start-byte-offset m)
Expand Down
4 changes: 2 additions & 2 deletions storm-core/src/ui/public/logviewer_search.html
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,12 @@
var file = $.url("?file");
var search = $.url("?search");
var offset = $.url("?offset") || 0;
var isDaemon = $.url("?is-daemon");
var isDaemon = $.url("?is-daemon") || "no";
file = decodeURIComponent(file);
search = decodeURIComponent(search);

$.get("/templates/logviewer-search-page-template.html", function(template) {
$("#search-form").append(Mustache.render($(template).filter("#search-single-file").html(),{file: file, search: search}));
$("#search-form").append(Mustache.render($(template).filter("#search-single-file").html(),{file: file, search: search, isDaemon: isDaemon}));

var result = $("#result");
var url = "/search/"+encodeURIComponent(file)+"?search-string="+search+"&start-byte-offset="+offset+"&is-daemon="+isDaemon;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
-->
<script id="logviewer-search-result-template" type="text/html">
{{#nextByteOffset}}
<a href="/logviewer_search.html?file={{file}}&search={{searchString}}&offset={{nextByteOffset}}" class="btn btn-default enabled">Next</a>
<a href="/logviewer_search.html?file={{file}}&search={{searchString}}&offset={{nextByteOffset}}&is-daemon={{isDaemon}}" class="btn btn-default enabled">Next</a>
{{/nextByteOffset}}
<table id="search-result-table" class="table table-striped compact">
<thead><tr><th>File offset</th><th>Match</th></tr></thead>
Expand All @@ -30,14 +30,15 @@
</tbody>
</table>
{{#nextByteOffset}}
<a href="/logviewer_search.html?file={{file}}&search={{searchString}}&offset={{nextByteOffset}}" class="btn btn-default enabled">Next</a>
<a href="/logviewer_search.html?file={{file}}&search={{searchString}}&offset={{nextByteOffset}}&is-daemon={{isDaemon}}" class="btn btn-default enabled">Next</a>
{{/nextByteOffset}}
</script>
<script id="search-single-file" type="text/html">
<form action="logviewer_search.html" id="search-box">
Search {{file}}:
<input type="text" name="search" value="{{search}}">
<input type="hidden" name="file" value="{{file}}">
<input type="hidden" name="is-daemon" value="{{isDaemon}}">
<input type="submit" value="Search">
</form>
</script>
Expand Down
57 changes: 49 additions & 8 deletions storm-core/test/clj/org/apache/storm/logviewer_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -397,10 +397,26 @@
27526
8888)))))

(testing "Logviewer link centers the match in the page (daemon)"
(let [expected-fname "foobar.log"]
(is (= (str "http://"
expected-host
":"
expected-port
"/daemonlog?file="
expected-fname
"&start=1947&length="
logviewer/default-bytes-per-page)
(logviewer/url-to-match-centered-in-log-page-daemon-file (byte-array 42)
expected-fname
27526
8888)))))

(let [file (->> "logviewer-search-context-tests.log.test"
(clojure.java.io/file "src" "dev"))]
(testing "returns correct before/after context"
(is (= {"searchString" pattern
(is (= {"isDaemon" "no"
"searchString" pattern
"startByteOffset" 0
"matches" [{"byteOffset" 0
"beforeString" ""
Expand Down Expand Up @@ -451,7 +467,8 @@

(let [file (clojure.java.io/file "src" "dev" "small-worker.log.test")]
(testing "a really small log file"
(is (= {"searchString" pattern
(is (= {"isDaemon" "no"
"searchString" pattern
"startByteOffset" 0
"matches" [{"byteOffset" 7
"beforeString" "000000 "
Expand All @@ -466,10 +483,29 @@
"&start=0&length=51200")}]}
(logviewer/substring-search file pattern)))))

(let [file (clojure.java.io/file "src" "dev" "small-worker.log.test")]
(testing "a really small log file (daemon)"
(is (= {"isDaemon" "yes"
"searchString" pattern
"startByteOffset" 0
"matches" [{"byteOffset" 7
"beforeString" "000000 "
"afterString" " 000000\n"
"matchString" pattern
"logviewerURL" (str "http://"
expected-host
":"
expected-port
"/daemonlog?file="
(.getName file)
"&start=0&length=51200")}]}
(logviewer/substring-search file pattern :is-daemon true)))))

(let [file (clojure.java.io/file "src" "dev" "test-3072.log.test")]
(testing "no offset returned when file ends on buffer offset"
(let [expected
{"searchString" pattern
{"isDaemon" "no"
"searchString" pattern
"startByteOffset" 0
"matches" [{"byteOffset" 3066
"beforeString" (->>
Expand Down Expand Up @@ -516,7 +552,8 @@
(is (= num-matches-found (count (get result "matches")))))))

(is
(= {"nextByteOffset" 6252
(= {"isDaemon" "no"
"nextByteOffset" 6252
"searchString" pattern
"startByteOffset" 0
"matches" [
Expand Down Expand Up @@ -602,7 +639,8 @@

(testing "Correct match offset is returned when skipping bytes"
(let [start-byte-offset 3197]
(is (= {"nextByteOffset" 6252
(is (= {"isDaemon" "no"
"nextByteOffset" 6252
"searchString" pattern
"startByteOffset" start-byte-offset
"matches" [{"byteOffset" 6246
Expand All @@ -623,7 +661,8 @@

(let [pattern (clojure.string/join (repeat 1024 'X))]
(is
(= {"nextByteOffset" 6183
(= {"isDaemon" "no"
"nextByteOffset" 6183
"searchString" pattern
"startByteOffset" 0
"matches" [
Expand Down Expand Up @@ -654,7 +693,8 @@

(let [pattern "𐄀𐄁𐄂"]
(is
(= {"nextByteOffset" 7176
(= {"isDaemon" "no"
"nextByteOffset" 7176
"searchString" pattern
"startByteOffset" 0
"matches" [
Expand All @@ -674,7 +714,8 @@

(testing "Returns 0 matches for unseen pattern"
(let [pattern "Not There"]
(is (= {"searchString" pattern
(is (= {"isDaemon" "no"
"searchString" pattern
"startByteOffset" 0
"matches" []}
(logviewer/substring-search file
Expand Down