Skip to content
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

push/pop() context #6

Closed
wants to merge 9 commits into from
Closed

push/pop() context #6

wants to merge 9 commits into from

Conversation

ixti
Copy link

@ixti ixti commented Apr 24, 2011

This patch gives ability to push and then pop context. e.g.:

logger.push('filters').debug('setting filters');
chains.forEach(function(chain) {
  logger.push(chain);
  chain.forEach(function(filter) {
    logger.debug('processing ' + filter.name);
  }
  logger.pop();
}
logger.pop();

will produce something like:

debug: [filters] setting filters
debug: [filters::before] processing needs_authentication
debug: [filters::before] processing inject_some_data

@ixti
Copy link
Author

ixti commented Apr 25, 2011

Added withContext() method to the pull request, so now it's also possible to do it like this:

var _logger = logger.withContext('filters').debug('setting filters');
chains.forEach(function(chain) {
  _logger.push(chain);
  chain.forEach(function(filter) {
    _logger.debug('processing ' + filter.name);
  }
  _logger.pop();
}

@indexzero
Copy link
Member

This looks interesting. Need some time to examine it.

Now pop() can receive `amount`, so:

- `logger.pop()` as well as `logger.pop(0)` equals to `logger.pop(1)`
- `logger.pop(-1)` equals to `logger.pop().pop().pop()`,
  when `logger` had three contexts registered
@ixti
Copy link
Author

ixti commented Apr 25, 2011

I have improved test to be more visual. Also I have improved pop() method, so now it's possible to pop(2) to pop out two last contexts or even pop(-1) to pop out all contexts.

@indexzero
Copy link
Member

Ok, lots of prep coming for NodeConf on our end. Will try to get this merged in before then.

@ixti
Copy link
Author

ixti commented Apr 25, 2011

Ok. Now it really works as expected ;))

@rgabo
Copy link

rgabo commented Jul 24, 2011

+1, also great for contextual information, such as associating user id / tracker with log statements for the same request.

e.g.

logger.push('user:42')

results in

info: [user:42] GET /foo
verbose: [user:42] stuff we do as part of request
info: [user:42] => 200 (0.52s)

this way it is easy to filter, even if concurrent requests mingle and have overlapping log lines. Today, we just pass { user: 42 } as metadata which is sub-optimal (line ends with user=42, but less readable)

@indexzero indexzero mentioned this pull request Jan 23, 2012
@ixti
Copy link
Author

ixti commented Jan 31, 2012

This shoud be rewritten. I agree about push/pop is not the best naming. IMHO the API should be like this:

// sync style
var ctx_logger = logger.context('foobar');

// async style (if callback given)
logger.context('foobar', function (logger) {
  // logger is context'ed logger here
});

@alampros
Copy link

I actually like the push/pop syntax a lot more. Either one would be good, but there something missing from the context style...maybe a method to read the context var (in order to append to it)?

I'd love to start using this!

@ixti
Copy link
Author

ixti commented Jan 31, 2012

Well, probably you're right. Basically I'm not against any name :)) so even if it will be push/pop then, probably it will be even more nicer:

//
// no block style, modify current logger's context
//

logger.push('a');
logger.debug('foobar');
// -> debug: [a] foobar

logger.push('b');
logger.debug('foobar');
// -> debug: [a - b] foobar

logger.pop();
logger.debug('foobar');
// -> debug: [a] foobar

//
// with block style, clone logger with new context
//

logger.push('c', function (logger) {
  setTimeout(function () {
    logger.debug('foobar');
    // -> debug: [a - c] foobar
  }, 10000);
});

logger.debug('foobar');
// -> debug: [a] foobar

@indexzero if you're OK with proposal, I'll be glad to update refactor and resend pull request

@indexzero
Copy link
Member

I'm not a fan of this API, but considering that I cant come up with a better naming convention and the value of the feature it makes sense. It should, however, be consistent with Javascript. It is not pushing and poping onto the logger it is unshifting and shifting

@ixti
Copy link
Author

ixti commented Jan 31, 2012

With all respect, I must disagree. We are pushing new value to the end of the context. And then poping one last value out.
So push(a), push(b) will give as ab, while unshift(a), unshift(b) should give ba. Context are used for easier debugging, so it's easier to red them from left to right - they follow deepness of the code.

Anyway this names were chosen not just because I like pushing'n'popping :)) but because this feature was "inspired" by log4j's nested diagnostic contexts (NDC): http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/NDC.html

@puzrin
Copy link

puzrin commented Feb 1, 2012

IMHO, shift/unshift is for arrays only - push/pop is more "natural" for loger object.

Anyway, nobody prohibits you to make alises, if methods name is a principal question.

@ixti
Copy link
Author

ixti commented Feb 1, 2012

This proposal adds a diagnostic context. Which in fact is some kind of array of breadcrumbs.

In context of method naming conventions:

  • we are shifting one element from the HEAD of the array
  • and unshifting into to the HEAD of an array
  • and we are pushing elements to the TAIL of the array
  • and poping them out from the TAIL later

Everytime we add new nested level - means we get deeper, so I really thing that push is more appropriate word for this situation. Let's say:

  • chooseCine() (NDC: 'home')
  • dressUp() (NDC: 'home')
  • getATaxi() (NDC: 'street')
    • driveToTheCine() (NDC: 'street - taxi')
  • buyTickets() (NDC: 'cine')
    • buyPopCorn() (NDC:'cine - lobby')
    • startWatchingMovie() (NDC: 'cine - movie')
      • buyPopCorn() (NDC: 'cine - movie - lobby')

@alampros
Copy link

alampros commented Feb 2, 2012

It occurred to me that this could take a cue from the webkit debugger commands console.group() and console.ungroup().
webkit

When it's not called directly from the console it looks a lot prettier - none of that undefined crap all over.

@ixti
Copy link
Author

ixti commented Feb 6, 2012

@indexzero can you please clarify your current position? Because I would like to fix my pull request in order to accelerate it's merge in ;)) as we wait almost one year now :))

@indexzero
Copy link
Member

Sorry guys. Been swamped with work at Nodejitsu.

I don't like inconsistent semantics, but I agree that unshift and shift are somewhat difficult for new users to understand. How about this?

//
// no block style, modify current logger's context
//

logger.prefix('a');
logger.debug('foobar');
// -> debug: [a] foobar

logger.prefix('b');
logger.debug('foobar');
// -> debug: [a - b] foobar

logger.unprefix();
logger.debug('foobar');
// -> debug: [a] foobar

//
// with block style, clone logger with new context
//

logger.prefix('c', function (logger) {
  setTimeout(function () {
    logger.debug('foobar');
    // -> debug: [a - c] foobar
  }, 10000);
});

logger.debug('foobar');
// -> debug: [a] foobar

@ixti
Copy link
Author

ixti commented Feb 12, 2012

If it's a big deal to have prefix/unprefix (btw by it's nature it should be appendPrefix, removeLastPrefix IMHO) insted of push/pop, then I can deal with that. The only thing I would like to ask in this case is to have prefix/unprefix to be aliases of push/pop :))

I believe that we must think about programmers. And I believe 100% of programmers (at least those who wasn't jailed in visual programming world of D bemole) will easily recognize push/pop :)) So I really think that having push/pop with prefix/unprefix aliases to them will be the best way.

@puzrin
Copy link

puzrin commented Feb 12, 2012

group / ungroup, offered by alampros, is also nice.

@ixti
Copy link
Author

ixti commented Feb 22, 2012

@indexzero, please, implement the way you like (method names etc) so rest of us will be able to start using it and bind our own aliases in worst case.

@puzrin
Copy link

puzrin commented Mar 5, 2012

indexzeeeeroooooooo !!! we are missing you :)

@kmpm
Copy link

kmpm commented Mar 7, 2012

+1 to the functionality. Bring it on whatever you call it.
While we are discussing method names... tag / untag could be an option

@indexzero
Copy link
Member

All, serious work at Nodejitsu is taking up my time this week. I know I owe some action here. I will get to it this weekend.

@berstend
Copy link

+1

@jfhbrook
Copy link
Contributor

I'm sorry to do this, but I'm going to close this pull request unmerged because, well, it's a year old. Again: I'm sorry.

If you would like to try again against the current codebase, I'll do my very best to handle it in a timely manner.

@jfhbrook jfhbrook closed this Oct 19, 2012
@dignifiedquire
Copy link
Contributor

@jesusabdullah I really need something like this, so I will implement it. But I would need to know what the preferred api is now, so it really gets merged and doesn't rot for a year.

@indexzero
Copy link
Member

@dignifiedquire It should look like #208. @clintandrewhall is a hero

@lobodpav
Copy link

lobodpav commented Jul 3, 2013

I know this issue was closed quite some time ago, but still - was this feature implemented somehow? This is a great idea with the prefixes I would love to use in my projects.

@clintandrewhall
Copy link
Contributor

@lobodpav Check the previously-mentioned pull request...?

@lobodpav
Copy link

lobodpav commented Jul 9, 2013

Well, I can do that, but this branch is quite an old one, isn't it? Was mainly wondering if this will ever became a part of a stable release.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet