Understanding parse_transforms via Lager in an LFE YAWS app.

101 views
Skip to first unread message

Paul Meier

unread,
Jan 17, 2015, 10:51:54 AM1/17/15
to lisp-flavo...@googlegroups.com
Hi friends!

I'm playing around with LFE for an app I'm writing, built off the yaws-rest-starter project, and I'm trying to use lager over the default YAWS logger. I'm running into a few issues, namely on what looks like applying the parse transform part of initialization (I know this because calls to `(lager:start)` appear to work correctly, but the actual logging functions supplied by the transform, such as `(lager:debug)` or `(lager:info)` return undef errors).

So I have a few questions when playing around here:

* I first tried adding the tuple `{parse_transform, lager_transform}` into erl_opts of the rebar.config per lager's README, but noticed that the rebar.config in the starter project only includes "test" as a srcdir. Even after adding "src," it didn't go through. Is there a way to include erl_opts to LFE source modules? More generally, would a parse transform even work on LFE code?

* I then tried the per-module solution of adding (what in vanilla Erlang) would be `-compile([{parse_transform, lager_transform}]).`, but trying variations of (compile '(#(parse_transform lager_transform))), (compile (list (tuple 'parse_transform 'lager_transform))) &c in the `(defmodule` seemed to yield the same error. Am I supplying it incorrectly?

I'm happy to provide any other info if you're curious. Thanks so much for your time :D

-Pablo

Duncan McGreggor

unread,
Jan 17, 2015, 12:08:55 PM1/17/15
to lisp-flavo...@googlegroups.com
Super-quick answer -- don't have time to dive in right now.

I had a problem loading up the lager include files (see this LFE ticket https://github.com/rvirding/lfe/issues/99). Robert's working on finishing that ticket.

Here's what I did to use (very simple) lager:
 * https://github.com/oubiwann/gae-lfe-yaws-sample-app/blob/master/src/sample-app-log.lfe

Hope that helps,

d


--
You received this message because you are subscribed to the Google Groups "Lisp Flavoured Erlang" group.
To unsubscribe from this group and stop receiving emails from it, send an email to lisp-flavoured-e...@googlegroups.com.
To post to this group, send email to lisp-flavo...@googlegroups.com.
Visit this group at http://groups.google.com/group/lisp-flavoured-erlang.
For more options, visit https://groups.google.com/d/optout.

Duncan McGreggor

unread,
Jan 17, 2015, 1:34:50 PM1/17/15
to lisp-flavo...@googlegroups.com
This may also be useful for you if you want to set up configurable log levels in your src/*.app.src file:
 * https://github.com/lfex/py/blob/master/src/py-logger.lfe

It's what I had to do in order to override basho's default logging behaviour. They presuppose the presence of an app.config file (which I didn't want to create), so I (brutally) overrode their defaults with the setup/0 function in that module.

I've just created a ticket so that LFE projects could do this with configuration instead:
 * https://github.com/lfex/lcfg/issues/2

d

Robert Virding

unread,
Jan 17, 2015, 3:54:47 PM1/17/15
to lisp-flavo...@googlegroups.com
Hi,

The major cause of your problems is that LFE can't handle parse transforms. These transform erlang abstract terms pretty much in the same way as macros. The LFE compiler does not generate erlang abstract terms but compiles directly to an internal form in the compiler called Core erlang. I will try and fix the macro issue Duncan mentioned.

We should maybe make an LFE include file for lager which calls the standard lager include to define the macros but does the lager parse transform as LFE macros. I have not looked at what the lager parse transform does so I have no idea how realistic this is.

Robert

Duncan McGreggor

unread,
Jan 17, 2015, 3:56:48 PM1/17/15
to lisp-flavo...@googlegroups.com
Oh, that's a nice idea...

d

--

Duncan McGreggor

unread,
Jan 21, 2015, 1:24:56 AM1/21/15
to lisp-flavo...@googlegroups.com
So whether we do macros, wrap function, etc., I've created a home for this effort :-)
 * https://github.com/lfex/logjam

There are 4 arities of log files provided right now, as the README details.

This was based on work done in the new lcfg library, which now supports a top-level "logging" directive in the lfe.config file.

The py project has just switched over to using logjam instead of its own hacks. I think I've got some hacks elsewhere, too -- I'll update them to use logjam as well.

The next effort is to figure out how to pass the calling module and function (via macros, possibly?) to the log functions instead of requiring that to be done manually right now.

Let me know if you have any issues with it,

d


On Sat, Jan 17, 2015 at 2:54 PM, Robert Virding <rvir...@gmail.com> wrote:

--

Robert Virding

unread,
Jan 22, 2015, 11:21:38 AM1/22/15
to lisp-flavo...@googlegroups.com
Does anyone have any information about exactly what the lager parse transform does. There is a chance we could solve this using macros. One problem would be handling the function call name as it as the form lager:something and this would be expanded by the LFE expander to (: lager something ...). I think, I will have to check *when* the conversion is done.

What exactly do we want? One solution would be include the file "l-lager.lfe" which contains the lager macros, perhaps by including "lager.hrl", and macros which do the same as the lager parse transform. It would still need to be able to call lager at compile time as the parse transform seems to do this.

Robert
To unsubscribe from this group and stop receiving emails from it, send an email to lisp-flavoured-erlang+unsub...@googlegroups.com.
To post to this group, send email to lisp-flavoured-erlang@googlegroups.com.

Duncan McGreggor

unread,
Jan 22, 2015, 12:24:28 PM1/22/15
to lisp-flavo...@googlegroups.com, and...@hijacked.us, jmer...@basho.com
Hey Robert,

I've included some lager contributors in this response (the creator and biggest contributor as well as the recent release manager) -- hopefully we can get this cleared up (I am afraid I don't know enough about lager to be able to answer with any confidence).

Andrew and Jon, as Robert asked below, we're trying to sort out what lager does with parse transforms so that LFE can duplicate this with macros (if possible) in the hopes that we can reuse the rest of lager (LFE can't use Erlang parse transforms).

From what I've seen, the parse transforms in lager allow lager to provide to various logs functions information such as calling module, calling function, line number of call, and process id of calling function. It also supports the user making additional data besides these (however, I don't know how much that last one depends upon parse transforms). The parse transoms are wrapped such that if a log level threshold is not met, nor more code than necessary is executed.

I am *deeply* unfamiliar with parse transforms in Erlang. If I have misspoken or misrepresented any aspect of how lager works, please correct me.

Andrew and Jon, if you have the time, we'd appreciate any clarification you can offer :-)

Thanks!

d


To unsubscribe from this group and stop receiving emails from it, send an email to lisp-flavoured-e...@googlegroups.com.
To post to this group, send email to lisp-flavo...@googlegroups.com.

Duncan McGreggor

unread,
Jan 22, 2015, 6:29:00 PM1/22/15
to Andrew Thompson, lisp-flavo...@googlegroups.com, and...@hijacked.us, jmer...@basho.com
Thanks, Andrew!

d

On Thu, Jan 22, 2015 at 4:45 PM, Andrew Thompson <and...@vm.hijacked.us> wrote:
On Thu, Jan 22, 2015 at 11:24:27AM -0600, Duncan McGreggor wrote:
> Hey Robert,
>
> I've included some lager contributors in this response (the creator and
> biggest contributor as well as the recent release manager) -- hopefully we
> can get this cleared up (I am afraid I don't know enough about lager to be
> able to answer with any confidence).
>
> Andrew and Jon, as Robert asked below, we're trying to sort out what lager
> does with parse transforms so that LFE can duplicate this with macros (if
> possible) in the hopes that we can reuse the rest of lager (LFE can't use
> Erlang parse transforms).
>
> >From what I've seen, the parse transforms in lager allow lager to provide
> to various logs functions information such as calling module, calling
> function, line number of call, and process id of calling function. It also
> supports the user making additional data besides these (however, I don't
> know how much that last one depends upon parse transforms). The parse
> transoms are wrapped such that if a log level threshold is not met, nor
> more code than necessary is executed.

Yes, this is the main thing that happens (although you could easily do
just this with a macro). The lager parse transform does a bunch of other
nice things with the callsite, it captures ?LINE, ?MODULE and function
(which isn't available via a builtin macro). If you don't have a parse
transform, though, I think it can all be done with macros (maybe not
function name capture, don't know if LFE exposes that). Lager also does
some other nice things with its parse transform, like stashing
information about records it has seen in the module, so they can be
prettyprinted later, and figuring out what application a module belongs
to (so you can partition logs by application).

All in all, though, you can probably do the majority of it with a macro.
Indeed, I've considered adding macros to lager so people can stop
complaining about the evils of parse transforms.

Andrew

Reply all
Reply to author
Forward
0 new messages