Skip to content

Commit

Permalink
[AIRFLOW-1498] Add optional analytics script to webserver html (apach…
Browse files Browse the repository at this point in the history
  • Loading branch information
ryw authored and Jing Guo committed Sep 2, 2019
1 parent 457cfb7 commit d929bdb
Show file tree
Hide file tree
Showing 8 changed files with 139 additions and 12 deletions.
4 changes: 4 additions & 0 deletions airflow/config_templates/default_airflow.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,10 @@ cookie_samesite =
# Default setting for wrap toggle on DAG code and TI log views.
default_wrap = False

# Send anonymous user activity to your analytics tool
# analytics_tool = # choose from google_analytics, segment, or metarouter
# analytics_id = XXXXXXXXXXX

[email]
email_backend = airflow.utils.email.send_email_smtp

Expand Down
11 changes: 10 additions & 1 deletion airflow/www/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -204,11 +204,20 @@ def init_plugin_blueprints(app):

@app.context_processor
def jinja_globals(): # pylint: disable=unused-variable
return {

globals = {
'hostname': socket.getfqdn(),
'navbar_color': conf.get('webserver', 'NAVBAR_COLOR'),
}

if 'analytics_tool' in conf.getsection('webserver'):
globals.update({
'analytics_tool': conf.get('webserver', 'ANALYTICS_TOOL'),
'analytics_id': conf.get('webserver', 'ANALYTICS_ID')
})

return globals

@app.teardown_appcontext
def shutdown_session(exception=None): # pylint: disable=unused-variable
settings.Session.remove()
Expand Down
26 changes: 26 additions & 0 deletions airflow/www/templates/analytics/google_analytics.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{#
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

#}
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');

ga('create', '{{ analytics_id }}', 'auto');
ga('send', 'pageview');
</script>
23 changes: 23 additions & 0 deletions airflow/www/templates/analytics/metarouter.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{#
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

#}
<script type="text/javascript">
!function(){var analytics=window.analytics=window.analytics||[];if(!analytics.initialize)if(analytics.invoked)window.console&&console.error&&console.error("MetaRouter snippet included twice.");else{analytics.invoked=!0;analytics.methods=["trackSubmit","trackClick","trackLink","trackForm","pageview","identify","reset","group","track","ready","alias","page","once","off","on"];analytics.factory=function(t){return function(){var e=Array.prototype.slice.call(arguments);e.unshift(t);analytics.push(e);return analytics}};for(var t=0;t<analytics.methods.length;t++){var e=analytics.methods[t];analytics[e]=analytics.factory(e)}analytics.load=function(t){var e=document.createElement("script");e.type="text/javascript";e.async=!0;e.src=("https:"===document.location.protocol?"https://":"http://")+"cdn.metarouter.io/a/v1/"+t+".js";var n=document.getElementsByTagName("script")[0];n.parentNode.insertBefore(e,n)};analytics.SNIPPET_VERSION="3.1.0";
analytics.load("{{ analytics_id }}");
analytics.page()
}}();
</script>
23 changes: 23 additions & 0 deletions airflow/www/templates/analytics/segment.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{#
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

#}
<script type="text/javascript">
!function(){var analytics=window.analytics=window.analytics||[];if(!analytics.initialize)if(analytics.invoked)window.console&&console.error&&console.error("Segment snippet included twice.");else{analytics.invoked=!0;analytics.methods=["trackSubmit","trackClick","trackLink","trackForm","pageview","identify","reset","group","track","ready","alias","debug","page","once","off","on"];analytics.factory=function(t){return function(){var e=Array.prototype.slice.call(arguments);e.unshift(t);analytics.push(e);return analytics}};for(var t=0;t<analytics.methods.length;t++){var e=analytics.methods[t];analytics[e]=analytics.factory(e)}analytics.load=function(t,e){var n=document.createElement("script");n.type="text/javascript";n.async=!0;n.src="https://cdn.segment.com/analytics.js/v1/"+t+"/analytics.min.js";var a=document.getElementsByTagName("script")[0];a.parentNode.insertBefore(n,a);analytics._loadOptions=e};analytics.SNIPPET_VERSION="4.1.0";
analytics.load("{{ analytics_id }}");
analytics.page();
}}();
</script>
27 changes: 16 additions & 11 deletions airflow/www/templates/appbuilder/baselayout.html
Original file line number Diff line number Diff line change
Expand Up @@ -75,15 +75,20 @@


{% block tail_js %}
{{ super() }}
<script type="text/javascript">
// below variables are used in base.js
var hostName = '{{ hostname }}';
var csrfToken = '{{ csrf_token() }}';
$("time[title]").tooltip()
</script>
<!--[if IE ]>
<script src="{{ url_for_asset('ie.js') }}" type="text/javascript"></script>
<![endif]-->
<script src="{{ url_for_asset('base.js') }}" type="text/javascript"></script>
{{ super() }}

<script type="text/javascript">
// below variables are used in base.js
var hostName = '{{ hostname }}';
var csrfToken = '{{ csrf_token() }}';
$("time[title]").tooltip()
</script>
<!--[if IE ]>
<script src="{{ url_for_asset('ie.js') }}" type="text/javascript"></script>
<![endif]-->
<script src="{{ url_for_asset('base.js') }}" type="text/javascript"></script>

{% if analytics_tool is defined and analytics_tool %}
{% include "analytics/" + analytics_tool + ".html" %}
{% endif %}
{% endblock %}
1 change: 1 addition & 0 deletions docs/howto/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,4 @@ configuring an Airflow environment.
check-health
define_extra_link
cli-completion
tracking-user-activity
36 changes: 36 additions & 0 deletions docs/howto/tracking-user-activity.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
.. Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
.. http://www.apache.org/licenses/LICENSE-2.0
.. Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
Tracking User Activity
=============================

You can configure Airflow to route anonymous data to
`Google Analytics <https://analytics.google.com/>`_,
`Segment <https://segment.com/>`_, or `Metarouter <https://www.metarouter.io/>`_.

Edit ``airflow.cfg`` and set the ``analytics`` block to have a ``tool`` and ``id``:

.. code-block:: python
[webserver]
# Send anonymous user activity to Google Analytics, Segment, or Metarouter
analytics_tool = google_analytics # valid options: google_analytics, segment, metarouter
analytics_id = XXXXXXXXXXX
.. note:: You can see view injected tracker html within Airflow's source code at
``airflow/www/templates/appbuilder/baselayout.html``. The related global
variables are set in ``airflow/www/templates/app.py``.

0 comments on commit d929bdb

Please sign in to comment.