-
Notifications
You must be signed in to change notification settings - Fork 8
finish 8th homework #42
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,21 +1,114 @@ | ||
(ns otus-16.homework) | ||
(ns otus-16.homework | ||
(:require | ||
[clojure.java.io :as io] | ||
[clojure.string :as str] | ||
[clojure.core.reducers :as r])) | ||
|
||
(def log-regex | ||
#"^([\d+.]+) (\S+) (\S+) (\[[\w+/]+:[\w+:]+ \+\d+\]) \"(.+?)\" (\d{3}) (\d+) \"([^\"]+)\" \"(.+?)\"") | ||
|
||
(defn parse-log | ||
[^String log] | ||
(let [[_ ip _ user-name date-time request response size referer user-agent] (re-find log-regex log)] | ||
{:ip ip | ||
:user-name user-name | ||
:date-time date-time | ||
:request request | ||
:response response | ||
:size size | ||
:referer referer | ||
:user-agent user-agent})) | ||
|
||
(defn solution [& {:keys [url referrer] | ||
:or {url :all referrer :all}}] | ||
(println "doing something") | ||
{:total-bytes 12345 | ||
;; если указан параметр url, то в хэш-мапе будет только одно значение | ||
:bytes-by-url {"some-url" 12345} | ||
;; если указан параметр referrer, то в хэш-мапе будет только одно значение | ||
:urls-by-referrer {"some-referrer" 12345}}) | ||
(defn get-logs-paths | ||
[dir-path] | ||
(->> (io/as-file dir-path) | ||
(file-seq) | ||
(filter #(.isFile %)))) | ||
|
||
(defn read-logs | ||
[logs] | ||
(map #(io/reader %) logs)) | ||
|
||
(defn ->url [log] | ||
{:pre [(contains? log :request)]} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. с pre и post условиями есть один нюанс - если |
||
(let [request (-> log :request)] | ||
(when request | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. а для чего тут when используется? ведь у функции есть проверка в блоке :pre |
||
(-> request | ||
(str/split #" ") | ||
second)))) | ||
|
||
(defn filter-by-url | ||
[url logs] | ||
(if (= url :all) | ||
logs | ||
(r/filter #(= url (->url %)) logs))) | ||
|
||
(comment | ||
(r/fold str (filter-by-url "test" [{:request "test"} {:request "test2"} {:request "test"}]))) | ||
|
||
(defn ->referer [log] | ||
{:pre [(contains? log :referer)]} | ||
(-> log :referer)) | ||
|
||
(defn filter-by-referer | ||
[referer logs] | ||
(if (= referer :all) | ||
logs | ||
(r/filter #(= referer (->referer %)) logs))) | ||
|
||
(defn close-logs | ||
[logs] | ||
(map #(.close %) logs)) | ||
|
||
(defn parse-int-safe | ||
[^String s] | ||
(try | ||
(Integer/parseInt s) | ||
(catch Exception _ | ||
0))) | ||
|
||
(defn sum-size | ||
[log-file] | ||
(->> log-file | ||
(r/map #(parse-int-safe (:size %))) | ||
(r/fold +))) | ||
|
||
(defn process-partition | ||
[logs {:keys [url referrer]}] | ||
(->> logs | ||
(r/map parse-log) | ||
(filter-by-url url) | ||
(filter-by-referer referrer))) | ||
|
||
(defn sum-partition | ||
[partition] | ||
(reduce #(+ %1 (sum-size %2)) | ||
0 | ||
partition)) | ||
|
||
(defn process-log | ||
[log-file filter-params] | ||
(->> log-file | ||
(line-seq) | ||
(partition-all 5000) | ||
(pmap #(process-partition % filter-params)) | ||
(sum-partition))) | ||
|
||
(defn solution | ||
[& {:keys [url referrer] | ||
:or {url :all referrer :all}}] | ||
(let [logs (-> "./logs" | ||
get-logs-paths | ||
read-logs)] | ||
(->> logs | ||
(pmap #(process-log % {:url url :referrer referrer})) | ||
(reduce +) | ||
(println "Bytes:")) | ||
(close-logs logs))) | ||
|
||
(comment | ||
;; возможные вызовы функции | ||
(solution) | ||
(solution :url "some-url") | ||
(solution :referrer "some-referrer") | ||
(solution :url "some-url" :referrer "some-referrer")) | ||
(time (solution)) | ||
(time (solution :url "/rss/")) | ||
(solution :referrer "some-referrer") | ||
(solution :url "some-url" :referrer "some-referrer")) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,20 @@ | ||
(ns otus-16.homework-test | ||
(:require [clojure.test :refer :all] | ||
[otus-16.core :refer :all])) | ||
[otus-16.homework :as sut])) | ||
|
||
|
||
(def stub-row "66.249.68.12 - - [20/Sep/2020:22:11:20 +0000] \"GET /%D0%BC%D0%B0%D0%BB%D0%B5%D0%BD%D1%8C%D0%BA%D0%B8%D0%B9-%D0%BC%D0%B0%D0%BB%D1%8C%D1%87%D0%B8%D0%BA-%D0%BF%D0%BE-%D0%B8%D0%BC%D0%B5%D0%BD%D0%B8-%D0%9D%D1%83%D1%80%D0%B1%D0%B5%D0%BA-%D0%B6%D0%B8%D0%BB-%D0%B2-%D0%BD%D0%B5%D0%B1%D0%BE%D0%BB%D1%8C%D1%88%D0%BE%D0%B9/?p=2 HTTP/1.1\" 304 0 \"-\" \"Mozilla/5.0 (Linux; Android 6.0.1; Nexus 5X Build/MMB29P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.110 Mobile Safari/537.36 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)\" \"-\"") | ||
|
||
(deftest parse-log-test | ||
(testing "parse-log" | ||
(is (= {:ip "66.249.68.12", | ||
:user-name "-", | ||
:date-time "[20/Sep/2020:22:11:20 +0000]", | ||
:request | ||
"GET /%D0%BC%D0%B0%D0%BB%D0%B5%D0%BD%D1%8C%D0%BA%D0%B8%D0%B9-%D0%BC%D0%B0%D0%BB%D1%8C%D1%87%D0%B8%D0%BA-%D0%BF%D0%BE-%D0%B8%D0%BC%D0%B5%D0%BD%D0%B8-%D0%9D%D1%83%D1%80%D0%B1%D0%B5%D0%BA-%D0%B6%D0%B8%D0%BB-%D0%B2-%D0%BD%D0%B5%D0%B1%D0%BE%D0%BB%D1%8C%D1%88%D0%BE%D0%B9/?p=2 HTTP/1.1", | ||
:response "304", | ||
:size "0", | ||
:referer "-", | ||
:user-agent | ||
"Mozilla/5.0 (Linux; Android 6.0.1; Nexus 5X Build/MMB29P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.110 Mobile Safari/537.36 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"} | ||
(sut/parse-log stub-row))))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍