Non puoi selezionare più di 25 argomenti Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri.

271 righe
7.0 KiB

10 anni fa
10 anni fa
10 anni fa
10 anni fa
10 anni fa
10 anni fa
10 anni fa
10 anni fa
  1. # Goldrush #
  2. Goldrush is a small Erlang app that provides fast event stream processing
  3. # Features #
  4. * Event processing compiled to a query module
  5. - per module protected event processing statistics
  6. - query module logic can be combined for any/all filters
  7. - query module logic can be reduced to efficiently match event processing
  8. * Complex event processing logic
  9. - match input events with greater than (gt) logic
  10. - match input events with less than (lt) logic
  11. - match input events with equal to (eq) logic
  12. - match input events with wildcard (wc) logic
  13. - match input events with notfound (nf) logic
  14. - match no input events (null blackhole) logic
  15. - match all input events (null passthrough) logic
  16. * Handle output events
  17. - Once a query has been composed the output action can be overriden
  18. with an erlang function. The function will be applied to each
  19. output event from the query.
  20. * Handle job execution and timing
  21. - create input events that include runtime on successful function executions.
  22. * Handle fastest lookups of stored values.
  23. - provide state storage option to compile, caching the values in query module.
  24. * Usage
  25. To use goldrush in your application, you need to define it as a rebar dep or
  26. include it in erlang's path.
  27. Before composing modules, you'll need to define a query. The query syntax
  28. matches any number of `{erlang, terms}' and is composed as follows:
  29. * Simple Logic
  30. - Simple logic is defined as any logic matching a single event filter
  31. Select all events where 'a' exists and is greater than 0.
  32. #+BEGIN_EXAMPLE
  33. glc:gt(a, 0).
  34. #+END_EXAMPLE
  35. Select all events where 'a' exists and is equal to 0.
  36. #+BEGIN_EXAMPLE
  37. glc:eq(a, 0).
  38. #+END_EXAMPLE
  39. Select all events where 'a' exists and is less than 0.
  40. #+BEGIN_EXAMPLE
  41. glc:lt(a, 0).
  42. #+END_EXAMPLE
  43. Select all events where 'a' exists.
  44. #+BEGIN_EXAMPLE
  45. glc:wc(a).
  46. #+END_EXAMPLE
  47. Select all events where 'a' does not exist.
  48. #+BEGIN_EXAMPLE
  49. glc:nf(a).
  50. #+END_EXAMPLE
  51. Select no input events. User as a black hole query.
  52. #+BEGIN_EXAMPLE
  53. glc:null(false).
  54. #+END_EXAMPLE
  55. Select all input events. Used as a passthrough query.
  56. #+BEGIN_EXAMPLE
  57. glc:null(true).
  58. #+END_EXAMPLE
  59. * Combined Logic
  60. - Combined logic is defined as logic matching multiple event filters
  61. Select all events where both 'a' AND 'b' exists and are greater than 0.
  62. #+BEGIN_EXAMPLE
  63. glc:all([glc:gt(a, 0), glc:gt(b, 0)]).
  64. #+END_EXAMPLE
  65. Select all events where 'a' OR 'b' exists and are greater than 0.
  66. #+BEGIN_EXAMPLE
  67. glc:any([glc:gt(a, 0), glc:gt(b, 0)]).
  68. #+END_EXAMPLE
  69. Select all events where 'a' AND 'b' exists where 'a' is greater than 1 and 'b' is less than 2.
  70. #+BEGIN_EXAMPLE
  71. glc:all([glc:gt(a, 1), glc:lt(b, 2)]).
  72. #+END_EXAMPLE
  73. Select all events where 'a' OR 'b' exists where 'a' is greater than 1 and 'b' is less than 2.
  74. #+BEGIN_EXAMPLE
  75. glc:any([glc:gt(a, 1), glc:lt(b, 2)]).
  76. #+END_EXAMPLE
  77. * Reduced Logic
  78. - Reduced logic is defined as logic which can be simplified to improve efficiency.
  79. Select all events where 'a' is equal to 1, 'b' is equal to 2 and 'c' is equal to 3 and collapse any duplicate logic.
  80. #+BEGIN_EXAMPLE
  81. glc_lib:reduce(
  82. glc:all([
  83. glc:any([glc:eq(a, 1), glc:eq(b, 2)]),
  84. glc:any([glc:eq(a, 1), glc:eq(c, 3)])])).
  85. #+END_EXAMPLE
  86. The previous example will produce and is equivalent to:
  87. #+BEGIN_EXAMPLE
  88. glc:all([glc:eq(a, 1), glc:eq(b, 2), glc:eq(c, 3)]).
  89. #+END_EXAMPLE
  90. * Composing Modules
  91. - All query modules must be compiled before use
  92. To compose a module you will take your Query defined above and compile it.
  93. #+BEGIN_EXAMPLE
  94. glc:compile(Module, Query).
  95. glc:compile(Module, Query, State).
  96. glc:compile(Module, Query, State, ResetStatistics).
  97. #+END_EXAMPLE
  98. - At this point you will be able to handle an event using a compiled query.
  99. Begin by constructing an event list.
  100. #+BEGIN_EXAMPLE
  101. Event = gre:make([{'a', 2}], [list]).
  102. #+END_EXAMPLE
  103. Now pass it to your query module to be handled.
  104. #+BEGIN_EXAMPLE
  105. glc:handle(Module, Event).
  106. #+END_EXAMPLE
  107. * Handling output events
  108. - You can override the output action with an erlang function.
  109. Write all input events as info reports to the error logger.
  110. #+BEGIN_EXAMPLE
  111. glc:with(glc:null(true), fun(E) ->
  112. error_logger:info_report(gre:pairs(E)) end).
  113. #+END_EXAMPLE
  114. Write all input events where `error_level' exists and is less than 5 as info reports to the error logger.
  115. #+BEGIN_EXAMPLE
  116. glc:with(glc:lt(error_level, 5), fun(E) ->
  117. error_logger:info_report(gre:pairs(E)) end).
  118. #+END_EXAMPLE
  119. * Composing Modules with stored state
  120. - You can create query modules with local state to compare to event data in `with' and `run'
  121. To compose a module with state data you will add a third argument (orddict).
  122. #+BEGIN_EXAMPLE
  123. glc:compile(Module, Query, [{stored, value}]).
  124. #+END_EXAMPLE
  125. * Accessing stored state data in constant time
  126. - You can use query modules in a way similar to mochiglobal
  127. Return the stored value in this query module.
  128. #+BEGIN_EXAMPLE
  129. {ok, value} = glc:get(stored).
  130. #+END_EXAMPLE
  131. * Job processing through composed modules
  132. - You can use query modules to execute jobs, if the job doesn't error, process an event.
  133. - `with' is similar to `run', the main difference is additional statistics and execution order
  134. To execute a job through the query module, inputting an event on success.
  135. #+BEGIN_EXAMPLE
  136. Event = gre:make([{'a', 2}], [list]).
  137. Result = glc:run(Module, fun(Event, State) ->
  138. %% do not end with {error, _} or throw an exception
  139. end, Event).
  140. #+END_EXAMPLE
  141. * Event Processing Statistics
  142. Return the number of input events for this query module.
  143. #+BEGIN_EXAMPLE
  144. glc:input(Module).
  145. #+END_EXAMPLE
  146. Return the number of output events for this query module.
  147. #+BEGIN_EXAMPLE
  148. glc:output(Module).
  149. #+END_EXAMPLE
  150. Return the number of filtered events for this query module.
  151. #+BEGIN_EXAMPLE
  152. glc:filter(Module).
  153. #+END_EXAMPLE
  154. * Job Processing Statistics
  155. Return the number of job runs for this query module.
  156. #+BEGIN_EXAMPLE
  157. glc:job_run(Module).
  158. #+END_EXAMPLE
  159. Return the number of job errors for this query module.
  160. #+BEGIN_EXAMPLE
  161. glc:job_error(Module).
  162. #+END_EXAMPLE
  163. Return the number of job inputs for this query module.
  164. #+BEGIN_EXAMPLE
  165. glc:job_input(Module).
  166. #+END_EXAMPLE
  167. Return the amount of time jobs took for this query module.
  168. #+BEGIN_EXAMPLE
  169. glc:job_time(Module).
  170. #+END_EXAMPLE
  171. * Some Tips & Tricks
  172. - This is really just a drop in the bucket.
  173. Return the average time jobs took for this query module.
  174. #+BEGIN_EXAMPLE
  175. glc:job_time(Module) / glc:job_input(Module) / 1000000.
  176. #+END_EXAMPLE
  177. Return the query combining the conditional logic of multiple modules
  178. #+BEGIN_EXAMPLE
  179. glc_lib:reduce(glc:all([Module1:info('query'), Module2:info('query')]).
  180. #+END_EXAMPLE
  181. * Build
  182. #+BEGIN_EXAMPLE
  183. $ ./rebar compile
  184. #+END_EXAMPLE
  185. or
  186. #+BEGIN_EXAMPLE
  187. $ make
  188. #+END_EXAMPLE
  189. * CHANGELOG
  190. 0.1.7
  191. - Add job execution and timings
  192. - Add state storage option
  193. 0.1.6
  194. - Add notfound event matching
  195. 0.1.5
  196. - Rewrite to make highly crash resilient
  197. - per module supervision
  198. - statistics data recovery
  199. - Add wildcard event matching
  200. - Add reset counters