Fork me on GitHub
#clojure-russia
<
2017-03-21
>
maxp09:03:53

а расскажите, уважаемые, как вы получаете source file/line в логах?

maxp09:03:07

кроме как через timbre

delaguardo10:03:50

@maxp например так

delaguardo10:03:56

(defmacro log [level message]
  `(do
     (def msg ~message)
     (let [m# (select-keys (meta #'msg) [:file :line :column])
           source# (str (:file m#) ":" (:line m#) ":" (:column m#))]
       (clojure.tools.logging/log ~level (str source# " " msg)))))

(log :info "some string")

delaguardo10:03:08

грязно, но работает

maxp10:03:25

тут def как-то не очень выглядит

maxp10:03:11

почему-то думал, что нумерация сорс строк в логах обычное дело

delaguardo10:03:22

как раз из-за def и считаю что это грязновато) но meta работает только для var ( так что так и не смог найти более элегантного решения

maxp10:03:43

?line (fline &form)

delaguardo10:03:54

file сам по себе норм, но не дает ни строки ни столбца откуда вызов происходит

maxp10:03:08

(defn- fline [and-form] (:line (meta and-form)))

delaguardo10:03:06

это nil всегда же

maxp10:03:42

я по макросам не специалист 🙂 но в timbre это все работает

maxp10:03:13

оно вообще приятная штука, но во всяких драйверах куча разного логгинга левого в slf4j

maxp10:03:33

и как-то хочется уменьшить разнообразие

maxp10:03:20

эта штука ?line (fline &form) внутри макроса

maxp10:03:29

и там &form срабатывает

delaguardo10:03:47

первый раз такую штуку вижу, не очень понятно что это такое

maxp10:03:58

еще есть &env

maxp10:03:01

тоже заняная

maxp10:03:07

тоже занятная

maxp10:03:41

но лично в меня макросы плохо идут - стараюсь их не писать без большой надобности 🙂

delaguardo10:03:35

действительно работает, крутяк

maxp10:03:07

то есть, как я понимаю тут просто надо так написать?

(defmacro log [level message]
  `(do
     (let [m# (select-keys (meta &form) [:file :line :column])
           source# (str (:file m#) ":" (:line m#) ":" (:column m#))]
       (clojure.tools.logging/log ~level (str source# " " msg)))))

(log :info "some string")

maxp10:03:37

и (do еще убрать

delaguardo10:03:47

(defn- fsource [and-form]
  (let [m (meta and-form)]
    (str *file* ":"
         (:line m) ":"
         (:column m))))

(defmacro log [level message]
  `(clojure.tools.logging/log ~level (str ~(fsource &form) " " ~message)))

delaguardo10:03:53

вот так получилось

delaguardo10:03:00

забавно, но у &form нет в метадате :file, поэтому нужно использовать *file* переменную

artemyarulin10:03:03

а это в CLJS работает?

delaguardo10:03:13

скорей всего да

delaguardo10:03:31

я что-то похожее делал для переводов a-la gettext

delaguardo10:03:44

но надо проверить

maxp10:03:56

а еще поясните для тупых, fsource в каком неймспейсе должна быть?

delaguardo10:03:30

где угодно, но разумно полоджить там же где макрос определен

maxp10:03:44

в смысле при развертывании макроса к ней подставится полный путь?

delaguardo11:03:08

а не, конечно же нет, она выполниться когда будет развернут макрос

delaguardo11:03:23

там же ~(fsource &form)

maxp11:03:52

ну то есть, если ее не будет в require :refer то облом

delaguardo11:03:32

если ее не будет в том неймспейсе где определен макрос, то да

delaguardo11:03:12

ее не обязательно реквайрить в тех неймспейсах где ты этот макрос будешь использовать

maxp11:03:38

ну то есть, когда все развернется, она будет филли квалифаед?

maxp11:03:45

ну то есть, когда все развернется, она будет фулли квалифаед?

maxp11:03:05

что-то я разучился тут сообщения редактировать 🙂

delaguardo11:03:29

там что-то с настройками надо сделать что бы было как раньше)

misha11:03:41

вы когда дообсуждаете, опубликуйте сниппет финальный для кложи и скрипта тут, спасибо opieop

maxp11:03:44

да, кстати, а file внутри функции, однако, не так как хотелось бы будет работать

maxp14:03:36

;;;;;; log macro ;;;;;;

;; <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %level %logger{16} %msg%n</pattern>

(defn- source-line [frm]
  (:line (meta frm)))
;

(defmacro log-debug [message & args]
  `(clojure.tools.logging/logp :debug
      (str ~(source-line &form) ": " ~message)
      ~@args))
;

(defmacro log-info [message & args]
  `(clojure.tools.logging/logp :info
      (str ~(source-line &form) ": " ~message)
      ~@args))
;

(defmacro log-warn [message & args]
  `(clojure.tools.logging/logp :warn
      (str ~(source-line &form) ": " ~message)
      ~@args))
;

(comment
  (log-debug "!debug!" 1 2 3)
  (log-info  "!info!" 1 2 3)
  (log-warn  "!warn!" 1 2 3))
;

delaguardo17:03:46

это по умолчанию

delaguardo17:03:44

а можно ли ротировать это для разных случаев?

delaguardo18:03:30

разобрался - это просто от мажорного мода зависит

andmed18:03:48

Привет всем. А что есть хорошего почитать по низкоуровневой стороне функциональных ЯП. Туда, в сторону железа и stack-based архитектуры cpu этой ленивости и higher order functions.. по сути о компиляции(интерпретации) в машиночитаемый код. хорошо бы без привязки к конкретной имплементации (яп).

andmed18:03:25

а то есть литература о компиляторах (си и вниз), есть о фп (вверх) а мостик чета не налаживается

mike_ananev18:03:22

Тут Тим Балдридж в соседней ветке интересные мысли выдает. У него спросили как было бы здорово если бы clojure комплилась в статичный код или хотя бы выполнялась на Go рантайме.

dottedmag18:03:27

@andmed сейчас найду тебе книжку

mike_ananev18:03:46

Even if you could compile Clojure to Go, I doubt it will be fast. There's a lot of stuff required by a functional language that Go just simply doesn't have.

mike_ananev18:03:29

I could imagine something like that really stressing Go's virtual dispatch and GC past the limits for which it was designed. (Tim Baldridge)

mike_ananev18:03:12

Hence my favorite saying: "You say X is faster than the JVM? Is it parallel, GC'd, dynamically JIT'd, dynamically typed, capable of handling tens of GB of data? If not...it's apples to oranges..."

mike_ananev18:03:47

просто понравились, довольно емкие цитаты

artemyarulin18:03:51

о фега се, книжка от Simon Peyton Jones, одного из авторов хаскеля, ня

dottedmag19:03:08

бумажка тоже от SPJ

andmed19:03:27

@mike1452 начитался тут умных мыслей что де в динамически типизированном языке нельзя поиметь GC. Но там неглупые люди тоже, решат. Что за ветка?

andmed19:03:44

@dottedmag спасибо большое, посмотрю

andmed19:03:27

Лишь бы они хаскелем не ограничились

dottedmag19:03:59

Они ограничились всеми ленивыми функциональными языками. Т.е. хаскелем 😃

dottedmag19:03:15

Если язык не ленивый, то компилятор у него обычный совершенно.

andmed20:03:15

Я бы и про обычно совершенно почитал. Aho дает примеры компиляции статического кода, до higher order functions не добирается

andmed20:03:14

Чистая ленивость хаскеля хороша в математике. Ну нижний слой это интересно совершенно да, лишь бы они тему не в своем стиле излагали (кмк сложном)

andmed20:03:44

Вообще когда я писал об implementation independent имел ввиду как раз хаскель ;)

andmed20:03:34

Может от aho там шажок маленький, отд рассмотрения не заслуживает...