ptarjan / node-cache

A simple in-memory cache for nodejs
BSD 2-Clause "Simplified" License
1.59k stars 214 forks source link

Get metadata about the cache entries #32

Open rprieto opened 9 years ago

rprieto commented 9 years ago

Hi,

It's very useful already how we can call cache.size(). What would you think of also exposing something like cache.entries() that gives you the list of keys, when they were last updated, and when they expire?

ptarjan commented 9 years ago

Hmm, could be useful. I worry people will use it in their normal control flows instead of just for analytics. How about only when debug mode is on?

rprieto commented 9 years ago

That's a good point, it should only be for analytics (e.g. logging cache stats every minutes, etc...).

I wouldn't want to turn on debug: true on production though because console.log has performance impacts. Would you be OK with a new stats: true then, that gathers stats when keys are set, and can be retrieved with cache.stats()? This shouldn't be noticeable on execution speed, and still be obvious it's meant for reporting purposes.

ps: I understand if you don't think that's the responsibility of node-cache, we could always keep/update a separate map of stats in our application. But I thought it'd be nice to have out of the box :)

ptarjan commented 9 years ago

That, or instead of returning the data, console.log() it so you clearly have to jump through hoops to use it programmatically.

rprieto commented 9 years ago

The way we'd like to use it though is for live reporting / monitoring. No runtime logic depends on it, but it still runs on production to gather and report data. For example, we can expose the age of key XYZ, and another process can monitor it & raise an alert if it wasn't updated in the last 5 minutes.

console.log could work (the other process just trawls the logs), but sadly it's a blocking IO call, so should never be turned on in production :frowning:

Some more flexible options would be logging the stats using our logging framework (Bunyan or any other), exposing the info from a /status route, or pushing the key's age (lastUpdate - Date.now()) to NewRelic. All 3 options Require the data to be available in JavaSript though. Thoughts?

ptarjan commented 9 years ago

Wow, I really dropped the ball on this. Did you solve it yourself? Thinking a bit more, adding something that makes you turn on debugging mode before you use it seems like the best option.

rprieto commented 9 years ago

Hi, no problem. We ended up maintaining another structure with the last updated date of each key.

Still interested in the idea of a {stats: true} option, which can optionally gather interesting stats (key updated dates, cache size...). The gathering/updating can probably happen on insert + expiry events.

One option if you're not too keen is maybe finding a way to plug into node-cache, for example inserted and expired events, so another bolt-on module can maintain stats.

ptarjan commented 9 years ago

It would be the same overhead for either. Checking a boolean or checking if there is an event callback. The boolean is simpler and I always like simplicity over extensibility, so I'd recommend that one if you coded it up I'd accept a PR.

rprieto commented 9 years ago

Sounds great thanks! Do you see { memSize, hitCount, missCount } moving into the stats structure?

ptarjan commented 9 years ago

Hmm. So debug is about spewing notices on events and stats is about introspecting the system while it is running? Sounds good.

rprieto commented 9 years ago

:+1: that's how I saw it, where you would not hopefully never turn on debug in production for too long (given console.log is blocking), but it's OK to turn on stats if you're interested in that.