Logging api

Reviewers:  @bernerdschaefer, @peterbourgon 

First pass at the internals of the logging API.  This is two layers thick.  There is a RingBuffer for log messages, and on top of this is a data structure that implements storage for and operations for each container.  (The RingBuffer probably should have been a separate submit.)

The next piece to be worked on will be the HTTP logging interface.
Changed as per discussion.


On Tue, Jul 29, 2014 at 4:21 PM, Peter Bourgon <notifications@github.com>
wrote:

> In harpoon-agent/logs.go:
>
> > +		case logActionListen:
> > +			containerLog := ls.getContainerLog(msg.containerID)
> > +			if containerLog.nextListenerID == math.MaxInt32 {
> > +				panic("Whoooaaa we've had 2^32 listeners.")
> > +			}
> > +			listenerID := containerLog.nextListenerID
> > +			containerLog.listeners[listenerID] = msg.logSink
> > +			containerLog.nextListenerID++
> > +			msg.listenerIDResult <- listenerID
> > +		case logActionDropListener:
> > +			delete(ls.getContainerLog(msg.containerID).listeners, msg.listenerID)
> > +		case logActionExit:
> > +			return
> > +		}
> > +	}
> > +}
>
> You're overloading logSetMsg with 5 different behaviors, depending on its
> action. Would it be better to have 5 distinct types, one per action, and
> 5 distinct channels on which you can select in this loop?
>
> —
> Reply to this email directly or view it on GitHub
> <https://github.com/soundcloud/harpoon/pull/13/files#r15525223>.
>