title: A pattern for transforming and combining multiple data types behind a simple interface
body: <p>I'm having difficulty conceptualizing a sane abstraction for a small event logging framework, and haven't come across anything comparable in the wild that would apply here.</p>
  
  <p>Overview: our web application needs to log events from the server side. The event data is json encoded to written to a flat file. An event might be a page view, a signup, an error condition, etc.</p>
  
  <p>All events would contain a set of core data, like web request information and session state. Any event should be able to define additional data to be recorded.</p>
  
  <p>Ideally, the interface to fire an event would be extremely minimal. Event definitions and data requirements should be defined in a single configuration file. Data validation and data transformations should be hidden behind this configuration file. In other words, the interface to log an event should require only an event name and the data structures to be transformed and recorded in the event.</p>
  
  <p>My original thinking was that a single data structure would be mapped to a single function whose responsibility is to transform the data structure into a dictionary that would eventually be merged into the final event object, then json encoded and written to the file. I'm referring to these as "composer" functions. In Django terms, something in the configuration file would map, for example, the HTTP request object that's passed to the view to a "request_composer" function. The function would construct a dictionary of data that's pulled out of that request object. The event that's emitted from the view would be required to pass in that "request" object.</p>
  
  <p>I suppose my question is if there is a pattern or abstraction that I've overlooked that cleanly transforms arbitrary data structures and merges them into a final data structure. I feel like this "single data type maps to a single transformation function" is a little kludgy and inelegant. It also breaks down when it makes sense for a single transformer to accept more than one argument.</p>