<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On 31 May 2016 at 19:42, Thomas Darimont <span dir="ltr">&lt;<a href="mailto:thomas.darimont@googlemail.com" target="_blank">thomas.darimont@googlemail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div>Hello Bill,</div><div><br></div><div>I didn&#39;t say that using JPA to store event data would lead to bad performance :-)</div><div>it&#39;s just that querying and aggregating event data via JPA(QL) is a pain ... </div><div>and I didn&#39;t want to potentially pull 100k+ events into memory to compute the stats in Java. </div><div><br></div><div>I wanted to keep the processing in the Keycloak JVM as low as possible to not risk any</div><div>OOME scenarios (though one could also use batch fetching here...).</div><div><br></div><div>That&#39;s the reason why I used a view that uses database specific means to do so.</div><div><br></div><div>With that said recording events with JPA is fine IMHO - though it could be done asynchronously in the background.</div><div>My current approach for computing stats only relies on the already stored event_entity data, </div><div>which of course needs to be persisted then - currently I don&#39;t need to store anything.</div><div><br></div><div>But since the event_entity data can be deleted I&#39;d proposed to periodically compute</div><div>aggregates based on those when a day is over. It could then compute stuff like:</div><div><br></div><div>* totalUserCount                 - how many users do we have in the realm?</div><div>* totalLoginCount                - how many users did login on that particular day?</div><div>* totalLoginFailedCount          - how many logins failed on that day?</div><div>* totalLoginBlockedCount         - how many failed logins lead to blocked accounts?</div><div>* totalRegisterCount             - how many users did register on that day?</div><div>* totalAbortedRegistrationsCount - how many users abandonned the registration?</div><div>- per realm per day.</div></div></blockquote><div><br></div><div>That sounds like a much better approach. Actually it could run every N minutes with the timer provider. If it only fetches the last N minutes of events it&#39;s not going to be a huge query, but probably still worth doing it in batches (1K max at the time or something?).</div><div><br></div><div>One issue here is that the timer is currently executed on all nodes, while this particular one should only run on one node.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><br></div><div>Similar stats could also be held by each keycloak instance in-memory and shared via infinispan.</div><div>Those stats could then also periodically aggregated (every 5 mins) to give information near real-time.</div></div></blockquote><div><br></div><div>Not sure that&#39;s necessary. Having the timer run periodically should be sufficient. It should definitively be a secondary requirement and possible to disable.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><br></div><div>Regarding the rare usage of this info I&#39;d argue that the dashboard should actually be the first</div><div>page that an administrator sees when logging in to Keycloak (after initial setup of course) - </div><div>I think it gives you a lot more than just a few stats - e.g. the possibility to login </div><div>see patterns and identify potential problems this probably consulted multiple times a day by multiple</div><div>people - especially if one uses a lot of different tenants.</div></div></blockquote><div><br></div><div>I agree it should be the main page, but thousands of users could be logging-in a second, while only one or two admins login to the admin console a day. So compared to logins, it&#39;s rare.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><br></div><div>Cheers,</div><div>Thomas</div></div><div class="HOEnZb"><div class="h5"><div class="gmail_extra"><br><div class="gmail_quote">2016-05-31 6:15 GMT+02:00 Bill Burke <span dir="ltr">&lt;<a href="mailto:bburke@redhat.com" target="_blank">bburke@redhat.com</a>&gt;</span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
  
    
  
  <div bgcolor="#FFFFFF" text="#000000">
    <p>I didn&#39;t read whole thread on this:  Having a JPA event store
      would be bad performance?  Isn&#39;t there more than one even per
      login?  That means multiple DB inserts per login just to gather
      stats.  Stats that would be looked at rarely (once a day?  once a
      week?  once a month?)  Just something to think about.<br>
    </p><div><div>
    <br>
    <div>On 5/29/16 4:52 PM, Thomas Darimont
      wrote:<br>
    </div>
    </div></div><blockquote type="cite"><div><div>
      <div dir="ltr">
        <div>Hello group,</div>
        <div><br>
        </div>
        <div>a few months ago I raised the feature request &quot;Activity
          dashboard&quot; in the Keycloak JIRA.</div>
        <div><a href="https://issues.jboss.org/browse/KEYCLOAK-1840" target="_blank">https://issues.jboss.org/browse/KEYCLOAK-1840</a></div>
        <div><br>
        </div>
        <div>This weekend I gave this a spin and I think I got pretty
          far with it,</div>
        <div>see attached annotated screenshot.</div>
        <div><br>
        </div>
        <div>The idea was to leverage the information from the stored
          event data</div>
        <div>to compute some Keycloak usage statistics over time.</div>
        <div>My current prototype supports JPA (user / event) storage
          provider</div>
        <div>and works with postgresql but could be adapted to other
          databases including MongoDB.</div>
        <div><br>
        </div>
        <div>Since I need to compute the usage statistics based on the
          event data,</div>
        <div>events need to be stored and some views (3) need to be
          defined to</div>
        <div>make the data accessible from JPA in a generic fashion.</div>
        <div><br>
        </div>
        <div>Since the queries are quite complex I wanted to keep them
          out</div>
        <div>of the code and therefore used named native queries via
          orm.xml.</div>
        <div>The actual queries use some database specific date/time
          functions</div>
        <div>that I wanted to keep out of the code - thus I created
          views </div>
        <div>that could be adapted for each database and provisioned via
          liquibase.</div>
        <div><br>
        </div>
        <div>The view definitions can be found here:</div>
        <div><a href="https://gist.github.com/thomasdarimont/24e11be101c6ed8773f22e1defc5d66e" target="_blank">https://gist.github.com/thomasdarimont/24e11be101c6ed8773f22e1defc5d66e</a></div>
        <div><br>
        </div>
        <div>For MongoDB one could define appropriate aggregation
          framework pipelines</div>
        <div>to express the same query logic.</div>
        <div><br>
        </div>
        <div>I basically exposed the data from those views per realm via
          a newly </div>
        <div>introduced AnalyticsProvider interface that is accessible
          via KeycloakSession.</div>
        <div><br>
        </div>
        <div>Data from this AnalyticsProvider is then exposed as a REST
          resource called &quot;DashboardResource&quot;.</div>
        <div>Data from this REST endpoint is then consumed by the admin
          frontend in a new section</div>
        <div>called &quot;dashboard&quot;.</div>
        <div><br>
        </div>
        <div>In the frontend I used basic patternfly components, e.g.:
          cards &amp; tables:</div>
        <div><a href="https://rawgit.com/patternfly/patternfly/master/tests/cards.html" target="_blank">https://rawgit.com/patternfly/patternfly/master/tests/cards.html</a></div>
        <div><br>
        </div>
        <div>For the heatmap I used <a href="http://cal-heatmap.com/#start" target="_blank">http://cal-heatmap.com/#start</a>
          which is based on d3js.</div>
        <div>There is also an angularjs directive that could be used as
          well.</div>
        <div><a href="https://github.com/shekhargulati/angular-cal-heatmap-directive" target="_blank">https://github.com/shekhargulati/angular-cal-heatmap-directive</a></div>
        <div><br>
        </div>
        <div>The current hacky code can be found here.:</div>
        <div><a href="https://github.com/thomasdarimont/keycloak/commits/poc/KEYCLOAK-1840-dashboard" target="_blank">https://github.com/thomasdarimont/keycloak/commits/poc/KEYCLOAK-1840-dashboard</a></div>
        <div><br>
        </div>
        <div>The relevant commit is:</div>
        <div><a href="https://github.com/thomasdarimont/keycloak/commit/40a7956f8e547edc148d2ddbaf27961f2a852203" target="_blank">https://github.com/thomasdarimont/keycloak/commit/40a7956f8e547edc148d2ddbaf27961f2a852203</a></div>
        <div><br>
        </div>
        <div>The code still needs a decent amount of polishing but I
          wanted to share this with</div>
        <div>you guys first to see if this could make it into Keycloak
          at some point.</div>
        <div><br>
        </div>
        <div>Cheers,</div>
        <div>Thomas</div>
      </div>
      <br>
      <fieldset></fieldset>
      <br>
      </div></div><span><pre>_______________________________________________
keycloak-dev mailing list
<a href="mailto:keycloak-dev@lists.jboss.org" target="_blank">keycloak-dev@lists.jboss.org</a>
<a href="https://lists.jboss.org/mailman/listinfo/keycloak-dev" target="_blank">https://lists.jboss.org/mailman/listinfo/keycloak-dev</a></pre>
    </span></blockquote>
    <br>
  </div>

<br>_______________________________________________<br>
keycloak-dev mailing list<br>
<a href="mailto:keycloak-dev@lists.jboss.org" target="_blank">keycloak-dev@lists.jboss.org</a><br>
<a href="https://lists.jboss.org/mailman/listinfo/keycloak-dev" rel="noreferrer" target="_blank">https://lists.jboss.org/mailman/listinfo/keycloak-dev</a><br></blockquote></div><br></div>
</div></div><br>_______________________________________________<br>
keycloak-dev mailing list<br>
<a href="mailto:keycloak-dev@lists.jboss.org">keycloak-dev@lists.jboss.org</a><br>
<a href="https://lists.jboss.org/mailman/listinfo/keycloak-dev" rel="noreferrer" target="_blank">https://lists.jboss.org/mailman/listinfo/keycloak-dev</a><br></blockquote></div><br></div></div>