Thursday, November 13, 2014

How to use impression Service In CQ/AEM

Use Case:
  1. You often have case where you want to use Impression service provided by CQ to do custom operation for example finding top 10 most viewed page or sorting all page based on there popularity.
  2. It might possible that your impression data (Page Views) is in external system and then you want to import those data as impression in CQ to have more application context.
  3. You want to aggregate all data across all publish instances.
Solutions:

Approach 1:

Creating your Own Impression service

You can create your own impression service by extending com.day.crx.statistics.Entry here is example
Supporting class



You need to embed following dependency for this
Here is example of how you can use this service

Now you can import data from external system (GA, Site Catalyst, Kafka) and then populate it using this service to your instance.

Once you are ready with all data you can use following service to use data,



Actual Implementation


Approach 2:

You don't want to write your own service as mentioned in Approach 1 and use OOTB service available to you. Only problem with this is, You have multiple publish instance and some how you want to combine all data in to one so that you get accurate picture. It kind of tricky to get all data from all publish instance (through reverse replication) and then combine them on author and then push them over again. However you can use one instance to collect all stat data (king of single source of truth and then replicate it back to all instance every day)


  • Make sure that you enable page view tracking by adding following line

           <cq:include script="/libs/foundation/components/page/stats.jsp" />
  • Then configure all publish instance to point to one DNS using following config (You can always override this under /apps)
           /apps/wcm/core/config.publish/com.day.cq.wcm.core.stats.PageViewStatistics
          /apps/wcm/core/config.publish/com.day.cq.wcm.core.stats.PageViewStatisticsImpl
         
  • make sure that pageviewstatistics.trackingurl is pointing to single domain (You need to create a domain, something like impression.mydomain.com that will be stand alone CQ instance to take all impression request)
  • Now you have consolidated page impression on one machine
  • You can easily write a schedular which will run every night and reverse replicate all data to author instance.
  • Once it is on author instance you can use replicator service to replicate to all other publish instance
  • Then you can use code mention in approach 1 to get popular resources.

Note: You can always use GA or something to track data. This is more useful if you want to do something internally and not want top share data with GA.

As usual feel free to ask any question you have.





9 comments:

  1. Yogesh,

    Can you please give me some pointers on how the statistics are replicated from the author to the publish instance? I see your comment "Once it is on author instance you can use replicator service to replicate to all other publish instance" but not quite sure how that is done.

    Do I need to write a custom OSGi service that hooks into the Sling Scheduler, and have that service activate /var/statistics to cause it to be replicated by the Default Replication Agent?

    Thanks!

    ReplyDelete
    Replies
    1. Hello Brett,

      To replicate you can simply use replicator service. https://docs.adobe.com/docs/en/aem/6-0/develop/ref/javadoc/com/day/cq/replication/Replicator.html Just store all document in a arraylist or something and then replicate them all using above service. Let me know if you need code example for this.

      Yogesh

      Delete
    2. Thanks for the quick reply Yogesh!

      Can you point me at any Adobe documentation on coding an implementation of Replicator? Also, is it possible to directly schedule the replicator to run once per day, or would that require hooking into the Sling Scheduler?

      Any code examples you have handy would be greatly appreciated.

      Thanks again!

      Delete
    3. Looking at Replicator, I see it's a service that I can simply inject and use (rather than implement). So that's simple enough. I think then I just need to understand how best to trigger it on a daily basis.

      Delete
    4. Here is example of replicator and tree activation:
      https://gist.github.com/yupadhyay/48a62cf34eaf762a72fa
      https://gist.github.com/yupadhyay/0f1cba64fbb32cd7f9c7

      Here is example of scheduler:
      http://wemcode.wemblog.com/cq-scheduler-example

      Let me know if that helps

      Delete
    5. Wow, this is absolutely fantastic. This should be everything I need! Thank you very much!

      I guess then the only question remaining is...why does AEM not have a UI function to do something like this, when it seems like such a pretty common use case to want to replicate nodes from author to publish (outside of page publishing, which of course is part of the UI).

      Barring OOTB UI support, the Replication Service/Helper you have written look to be quite valuable for implementing this via code. Have you considered submitting these to ACS AEM Commons (http://adobe-consulting-services.github.io/acs-aem-commons/)?

      Delete
    6. Hello Brett,

      CQ support replicate tree feature to replicate part of tree using UI. More information https://docs.adobe.com/docs/en/cq/5-6-1/wcm/page_publish.html note that for some reason this UI is missing in AEM6.1 but you can simply create package of this from CQ5.6.1 and install it on AEM6.1

      Yogesh

      Delete
    7. If you're talking the "Activate Tree" UI - I can select /var/statistics/pages from there, but it will not replicate those over (wondering if it only includes certain node types?) Even if it did work, though, writing a scheduler service would still be necessary.

      On a different note, have you considered submitting your Replication ServiceHelper to ACS AEM Commons? They seem to be very open to pull requests.

      Delete
  2. This comment has been removed by the author.

    ReplyDelete