Blog Analityczny. Narzędzia. Techniki. Rozwiązania Analityczne.

Google Tag Manager Server Side. Proces implementacji krok po kroku via AppEngine

02.2023 | Google Tag Manager Server Side | Google Analytics 4 | App Engine

Uwaga: Artykuł opisuje implementację via AppEngine. Obecna implementacja GTM Server-Side wykorzystuje Cloud Run. Jeżeli jesteś zainteresowany najnowszą implementacją z wykorzystaniem Cloud Run to kliknij w artykuł: Implementacja GTM Server-Side via Cloud Run.


Rok 2023 to rok, który w analityce stoi pod znakiem migracji Google Analytics z wersji Universal do Google Analytics 4. Migracja jest dużym wyzwaniem, ale równocześnie jest też dużą szansą, aby spojrzeć raz jeszcze na potrzeby firmy związane ze zbieraniem danych tzn.

  • Czy model, z którego korzystaliśmy dotąd, się sprawdził
  • Czy decydenci korzystali z danych i czuli do nich zaufanie
  • Czy dane miały realny wpływ na naszą organizację

Czy też ...

... dotychczasowa implementacja była pełna błędów i nie budziła zaufania, a zatem nikt z niej nie korzystał. Chociaż oficjalnie nikt tego nie przyznawał.

Szczególnie, w tym drugim przypadku, nasza firma dostaje drugą szansę. Możemy raz jeszcze podejść, od zera do implementacji Analyticsa i to nie tylko od strony czysto technicznej, ale przede wszystkim od strony czysto biznesowej => przejść transformację na organizację data-driven.

To również doskonała szansa, aby wraz z implementacją GA4, przejść również przez proces migracji Google Tag Managera na wersję server-side. A dokładniej, obok tradycyjnego kontenera wdrożyć, dodatkowy kontener działający w warstwie serwera.

W niniejszym artykule naświetlimy kolejne kroki, związane z implementacją GTM Server-Side, jego kosztami oraz plusami i minusami omawianego wdrożenia.

Uwaga: proces budujemy totalnie od początku, od momentu utworzenia konta GA, GTM, aż po deploy do Google Cloud Platform.

Przykładowe rozwiązanie będzie oparte o wdrożenie kontenera server side w domenie analyticslab.biz. Natomiast do serwowania kontenera wykorzystamy subdomenę gtm.analyticslab.biz.

W uproszczeniu, wdrożenie składa się z dwóch elementów:

  • Utworzenie kontenera GTM w wersji server-side
  • Utworzenie (setup) servera do obsługi kontenera serwerowego GTM

Link do dokumentacji:

Zaczynamy zatem.

Krok 1. Utworzenie kontenera serwerowego GTM

Logujemy się do swojego konta GTM i klikamy Create Account, aby utworzyć konto Tag Managera dla domeny analyticslab.biz:

W konfiguratorze nowego konta wybieramy opcję Server i klikamy przycisk Create.

Następnie potwierdzamy regulamin usługi.

Tag Manager w wersji Server Side został utworzony, nie jest to jednak koniec konfiguracji. W dalszych krokach musimy uruchomić kontener GTM na serwerze => w naszym przypadku (i rekomendowanym) na Google Cloud Platform.

Krok 2. Deploy GTM Server Side do Google Cloud Platform

Przed wykonaniem deployu kontenera GTM do Google Cloud Platform, należy sprawdzić, czy:

  • Mamy utworzone konto GCP dla naszej organizacji => konto musi być dostępne pod tym samym adresem email co dostęp do kontenera GTM.
  • Konto GCP ma aktywny biling tzn. jest podpięta i aktywna karta płatnicza
  • Mamy uprawnienia typu Project Creator i Billing Account User

Jeżeli nie mamy konta bilingowego, to musimy wpierw przejść do panelu Google Cloud Platform (adres: https://console.cloud.google.com/), a następnie wybrać pozycję:

Biling z głównego menu:

I dalej kliknąć przycisk Create Account:

I utworzyć nowe konto bilingowe, wpisując dane do faktury oraz dane karty płatniczej (i/lub kredytowej):

Po wpisaniu danych bilingowych wracamy do deployu kontenera GTM.

Mamy dwie możliwości instalacji kontenera GTM:

  • Instalacja automatyczna
  • Instalacja ręczną

W większości przypadków wystarczająca jest instalacja automatyczna i taką też rekomendujemy przeprowadzić.

Ręczna instalacja kontenera może być użyteczna np. jeżeli rozważamy inne serwery, niż te w oferowane w ramach Google Cloud Platform => bo wybór GCP nie jest obowiązkowy, możemy nasz kontener hostować w innej chmurze.

Widok dla wyboru ręcznej ścieżki instalacji kontenera GTM:

Krok 3. Wybór bilingu i utworzenie konta

Pierwszym elementem procesu automatycznej instalacji jest wybór konta bilingowego tzn. konta, z którego będą pobierane opłaty za wykorzystanie zasobu platformy Google Cloud. Na ekranie zobaczymy listę dostępnych kont bilingowych oraz przycisk zatwierdzenia jednego z nich.

Po zatwierdzeniu, rozpoczyna się proces utworzenia serwera - wymaga to odczekania kilku minut, podczas których jest fizycznie uruchamiana nasza instancja.

Krok 4. Zakończenie procesu utworzenia serwera

Jako zakończenie procesu instalacji, powinniśmy zobaczyć planszę z napisem "Server Created". Należy zapisać dane, które pojawią się na ekranie potwierdzającym utworzenie serwera => będą one potrzebne w kolejnych krokach.

Na marginesie

Na moment zatrzymajmy się i zastanówmy => Co właściwie się stało? Jaka operacja została wykonana?

Odpowiadamy:

Został utworzony projekt GCP z kontenerem po stronie serwera, wdrożonym na jednym serwerze App Engine F1, w standardowym środowisku (Standard environment). Jest to środowisko rekomendowane do procesu konfiguracji i testowania. Dla celów produkcyjnych, zalecane jest środowisko "elastyczne" - Flexible environment.

Dokumentacja => szczegóły środowiska App Engine i planu Standard environment można znaleźć tutaj:

Plan Standard, to plan, w którym dostępne są predefiniowane instancje, jak B1, B2 etc. Wybieramy jedną z nich i ponosimy zdefiniowany koszt per godzina pracy, mając do dyspozycji zdefiniowany zakres mocy.

Poniżej znajduje się specyfikacja dla planu Standard:

Instance Class Memory Limit CPU Limit Supported Scaling Types
F1 (default) 256 MB 600 MHz automatic
F2 512 MB 1.2 GHz automatic
F4 1024 MB 2.4 GHz automatic
F4_1G 2048 MB 2.4 GHz automatic
B1 256 MB 600 MHz manual, basic
B2 (default) 512 MB 1.2 GHz manual, basic
B4 1024 MB 2.4 GHz manual, basic
B4_1G 2048 MB 2.4 GHz manual, basic
B8 2048 MB 4.8 GHz manual, basic

 

Opis poszczególnych klas w instancji Standard można znaleźć tutaj:

W planie Flexible ponosimy natomiast koszt per sekunda (koszt wykorzystania zasobu), przy czym minimalna jednostka to jedna minuta. Kluczowa różnica pomiędzy środowiskami, to fakt, że Flexible daje dostęp do SSH i wsparcie dla docker-a. Tym samym są tu większe możliwości do implementacji i integracji z własnym środowiskiem.

Poniżej natomiast znajduje się tabela opisująca (porównująca) parametry planu Standard vs Flexible:

Feature Standard environment Flexible environment
Instance startup time Seconds Minutes
Maximum request timeout Depends on the runtime and type of scaling. 60 minutes
Background threads Yes, with restrictions Yes
Background processes No Yes
SSH debugging No Yes
Scaling Manual, Basic, Automatic Manual, Automatic
Scale to zero Yes No, minimum 1 instance
Writing to local disk
  • Java 8, Java 11, Java 17, Node.js, Python 3, PHP 7.X, PHP 8.1, Ruby, Go 1.11, and Go 1.12+ have read and write access to the directory.
  • Python 2.7 and PHP 5.5 don't have write access to the disk.
Yes, ephemeral (disk initialized on each VM startup)
Modifying the runtime No Yes (through Dockerfile)
Deployment time Seconds Minutes
Automatic in-place security patches Yes Yes (excludes container image runtime)
Access to Google Cloud APIs Services such as Cloud Storage, Cloud SQL, Memorystore, Google Tasks and others. Yes Yes
WebSockets No
Java 8, Python 2, and PHP 5 provide a proprietary Sockets API (beta), but the API is not available in newer standard runtimes.
Yes
Supports installing third-party binaries
  • Yes for Java 8, Java 11, Java 17, Node.js, Python 3, PHP 7.X, PHP 8.1, Ruby, Go 1.11, and Go 1.12+.
  • No for Python 2.7 and PHP 5.5.
Yes
Location North America, Asia Pacific, or Europe North America, Asia Pacific, or Europe
Pricing Based on instance hours Based on usage of vCPU, memory, and persistent disks

Sprawdźmy teraz utworzony projekt, w Google Cloud Platform.

Krok 5. Przechodzimy do Google Cloud

W tym celu, przechodzimy pod adres => https://console.cloud.google.com/

I wybieramy projekt, zaczynający się od prefiksu GTM-[tu_ciąg_znaków]

Widzimy tutaj oznaczenie wersji => testing. Widzimy również informacje o ruchu / obciążeniu serwera App Engine.

Czas zatem na kolejny krok, czyli konfigurację domeny, na której znajdzie się nasz serwer z uruchomionym Tag Managerem.

Krok 7. Domena. Konfiguracja domeny pod serwer tagowania

Dokumentacja źródłowa (Custom domain config):

Dlaczego potrzebujemy subdomeny?

Domyślnie serwer wykorzystuje adres w domenie appspot.com. Powinniśmy zmienić ten adres na własną subdomenę np.

gtm.nazwa_naszej_domeny.pl

Wykorzystanie własnej subdomeny daje nam gwarancje traktowania ruchu, plików cookies jako First-Party a nie Third-Party.

Proces utworzenia subdomeny rozpoczynamy od przejścia do Google Cloud i wyboru:

Menu główne > App Engine > Settings

Następnie wybieramy zakładkę Custom Domains:

I przechodzimy do kreatora dodania domeny - w pierwszym kroku podajemy nazwę naszej subdomeny:

  • gtm.analyticslab.biz

Nazwa subdomeny może być wybrana dowolnie, nie ma to wpływu na działanie serwera, a zatem możemy wykorzystać nazwy np.

  • ss.nasza-domena
  • gtm.nasza-domena
  • ga.nasza-domena
  • tracking.nasza-domena
  • pomidor.nasza-domena

Weryfikacja własności domeny.

W trakcie procesu dodania domeny, musimy potwierdzić, że mamy dostęp do domeny I możemy ną zarządzać. W tym celu wybieramy jedną z metod weryfikacji.

Domyślnie jest to metoda, polegająca na dodaniu rekordu TXT do strefy DNS obsługującej naszą domenę. Weryfikacja własności domeny odbywa się poprzez interfejs Webmaster Central:

Pamiętajmy, że dodanie rekordu do domeny może wymagać odczekania dłuższego czasu, nim stanie się on publicznie dostępny (czas propagacji zmian w serwerach DNS => czas ten może być różny zależnie od providera).

Po uzyskaniu pozytywnej weryfikacji, powinniśmy zobaczyć ekran podobny do poniższego:

Jeżeli domena jest zweryfikowana w Webmaster Central, to pozostaje kliknięcie przycisku Refresh Domains:

Domena jest na liście dostępnych, zatem klikamy przycisk Continue i przechodzimy do kolejnego ekranu:

Ekranu, który nas informuje o mapowaniu domeny gtm.analyticslab.biz na kontener GTM o identyfikatorze X, działający w ramach danego konta GCP:

Przechodzimy do kolejnego ekranu:

I dostajemy informację o rekordach DNS, jakie musimy dodać do konfiguracji naszej domeny. Te rekordy to:

  • Rekord A
  • Rekord AAAA
  • Rekord CNAME

Dodatkowe rekordy wprowadzamy w panelu naszego registrara - czyli firmy hostingowej, w której zakupiliśmy i utrzymujemy domenę. W większości przypadków, w panelu znajdziemy przycisk lub link zatytułowany "edycja strefy DNS" lub "zarządzanie domeną".

=> otwieramy zatem nową zakładkę i przechodzimy do panelu rejestratora domeny

Po dokonaniu niezbędnych ustawień w strefie DNS naszej subdomeny, wracamy do interfejsu Google Cloud Platform, klikamy przycisk "Done" i przechodzimy do kolejnego ekranu.

Na ekranie - w kolejnym kroku - możemy zaobserwować generowanie certyfikatu SSL dla naszej subdomeny:

Aktywacja certyfikatu zostanie potwierdzona dyskretnym komunikatem:

Tym samym zakończyliśmy wszystkie prace, związane z konfiguracją GTM server-side i hostingu tego tagu w ramach Google Cloud Platform.

Kolejne kroki obejmują implementację trackowania na naszej stronie internetowej.

Strona www. Implementacja kodu.

Punkt ten może wydawać się kontrowersyjny tzn. jaki dodatkowy kod jest potrzebny, skoro korzystamy z implementacji Server-Side?

De facto, nasza implementacja nie jest w pełni serwerowa. Jest to raczej implementacja typu klient - serwer, gdzie zwyczajnie mamy kontrolę nie tylko nad klientem, ale i nad serwerem.

Pełna implementacja serwerowa ma jednak miejsce, wtedy gdy korzystamy z Measurement Protocol i implementujemy Analyticsa w całości po stronie aplikacji.

W przypadku naszej obecnej sytuacji:

  • => mamy tag serwerowy GTM Server-Side
  • => potrzebujemy jeszcze tag po stronie klienta, który będzie komunikował się z GTM Server-Side

W tym celu możemy wykorzystać albo:

  • Drugi kontener GTM, ale w tradycyjnej konfiguracji (nie Server-Side)
  • Kontener GTAG

W naszym przykładzie, implementację GTM Server-Side na stronie analyticslab.biz, oprzemy o kontener GTAG.

Implementacja tagu GTAG

Tag ten implementujemy w ramach kodu naszej strony www. Kod można pobrać z sekcji Admin w ramach Google Analytics.

Krok 1. Wybieramy platformę => tagujemy stronę WWW, tak więc wybieramy opcję Web:

Krok 2. Podajemy niezbędne dane => adres url i nazwę dla strumienia danych (stream name):

Krok 3: Kopiujemy kod GTAG:

Zasady implementacji kodu GTAG

Tag implementujemy zaraz po otwarciu znacznika <head>. Równocześnie konieczna jest zmiana w kodzie tagu GTAG, tak aby dane były wysyłane do naszej instancji serwerowej GTM, zamiast do instancji domyślnej.

W tym celu kod domyślnego tagu:

 

<!-- Google tag (gtag.js) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-9SMG2F0NSK"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-9SMG2F0NSK');
</script>

 

 

Zmieniamy do poniższej postaci:

<!-- Google tag (gtag.js) -->
<script async src="https://gtm.surowiecki.org/gtag/js?id=G-FXHP7TLLGC"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-FXHP7TLLGC', {
transport_url: 'https://gtm.surowiecki.org',
});
</script>

 

 

 

Jak można zauważyć, pojawił się tu fragment: transport_url: 'https://gtm.surowiecki.org'

 

 

Transport_URL to parametr, który pozwala wysyłać dane do dowolnego endpoint-a.

Podsumujmy:

  • Mamy przygotowany i działający kontener GTM (działający na skonfigurowanym koncie Google Cloud Platform)
  • Mamy zaimplementowany "kod klienta", w postaci tagu GTAG

Aby dane ze strony były zbierane, to potrzebujemy teraz skonfigurować tag Google Analytics w ramach naszego kontenera GTM.

Konfiguracja GTM Server-Side

Krok 1. Sekcja Tags

Dodajemy nowy tag => Google Analytics: GA4

Tag konfigurujemy wg poniższego schematu:

Gdzie Measurement ID jest identyfikatorem naszej usługi Google Analytics 4.

Krok 2. Sekcja Triggers

Trigger to reguła, która powoduje, że nasz tag śledzący GA4 zostaje uruchomiony. Wybieramy trigger typu Custom a jako regułę uruchomienia ustawiamy:

Client Name equals GA4

Krok 3. Sekcja Clients

Na koniec pozostaje nam edycja ustawień w sekcji Clients - wybieramy tutaj tag GA4.

Poniżej znajduje się ekran z wprowadzoną konfiguracją - najważniejsze punkty to podanie naszego identyfikatora usługi Google Analytics 4 oraz zaznaczenie opcji Server Managed dla plików cookies.

Kolejny krok to dodanie tagu Google Analytics 4

Krok 4. Weryfikacja konfiguracji

Weryfikacja konfiguracji może być zrealizowana na dwa sposoby:

Sposób 1. Wchodzimy na naszą stronę www i sprawdzamy, czy widać wizytę w widoku czasu rzeczywistego Google Analytics 4.

Sposób 2. Wykorzystujemy tryb debug wbudowany w Google Tag Managera.

W tym celu przechodzimy przez kolejne kroki:

I. Uruchamiamy tryb Preview

II. Wybieramy opcję Send requests manually

Po kliknięciu tej opcji otrzymamy następujący ekran:

Kopiujemy z niego przykładowe zapytanie CURL.

III. Przechodzimy do terminala (Linux / MacOS) lub w przypadku Windows uruchamiamy terminal Linuxa lub wcześniej instalujemy CURL for Windows.

Uwaga:

Uruchamiamy nasz kod w terminalu:

Wynik wywołania możemy obserwować w interfejsie Preview:

Mamy zatem zakończoną i zweryfikowaną implementację Google Analytics 4 wraz z Google Tag Manager Server Side.

Pozostaje nam jeszcze kwestia startu produkcyjnego, a tym samym wybór odpowiedniej konfiguracji (planu) dla naszego serwera odpowiedzialnego za kontener GTM.

Start produkcyjny. Zalecenia Google

Cennik usługi Google Cloud Platform, w zakresie hostingu kontenera GTM został przedstawiony już we wcześniejszym fragmencie niniejszego posta.

Rekomendacja Google, w zakresie wyboru i kosztu maszyny produkcyjnej jest jak poniżej:

Using App Engine in production
In production configuration, each server costs approximately $40 / month (USD). Each server is an App Engine instance with 1 vCPU, 0.5 GB memory, 10 GB disk in the Flexible environment.

W konfiguracji produkcyjnej każda instancja kosztuje około 40 USD / miesiąc. Na wyposażeniu ma 1 procesor wirtualny, 0,5 GB pamięci, 10 GB dysku w środowisku elastycznym.

Rekomendujemy uruchomienie minimum 3 instancji, tak aby zminimalizować ryzyko utraty danych w przypadku obciążenia systemu. Oceniamy, że 3-6 instancji jest w stanie obsłużyć 50-200 requestów per sekunda.

A zatem, w przypadku np. 6 instancji App Engine koszt wyniesie około 6 * 50 USD = 240 USD.

Należy jednak pamiętać, że ostateczny koszt zależy od ilości tagów jakie mamy, od zakresu danych jakie przesyłamy i to my decydujemy o tym ile instancji uruchomić.

Warto zatem rozpocząć od minimalnych wartości i następnie stopniowo zwiększać, jeżeli jest taka potrzeba.

Warto również dobrze przemyśleć zakres danych, jakie zbieramy i przesyłamy - jeżeli mamy takie, które nie były analizowane w ostatnich 3 miesiącach, to można uznać je za bezwartościowe.

Zmiana serwera na produkcyjny

Przejdź do Cloud Shell

Uruchamiamy kreator konfiguracji. Służy do tego polecenie:

  • gcloud config set project tu-podaj-ID-twojego-projektu

A następnie:

  • bash -c "$(curl -fsSL https://googletagmanager.com/static/serverjs/setup.sh)"

W konfiguratorze, w pozycji Deployment Type, należy podać wartość production:

Pełne kroki deployu można prześledzić na poniższym wydruku z konsoli Google Cloud.

Przykładowy skrypt konfiguracji, jaki wypełniamy w trakcie omawianego procesu deployu do produkcji:

Na zółto są zaznaczone wartości, które wpisujemy:

Container Config (Current: aWQ9R1RNL*******):

Policy Script URL (Optional):

Request Logging (Current: on): off #można wpisać off, jeżeli zależy nam na optymalizacji kosztu. Ja jednak zostawiam to na "on"

Deployment Type (Current: testing): production

Autoscaling (Recommended: on): on

Number of Servers (Recommended: 3): 3

NOTE: You are upgrading from a testing deployment to a production

deployment. The linked billing account will start incurring charges.

Do you wish to continue? (y/N): y

Klikamy oczywiście Yes, czyli "y". Rozpoczyna się deploy do produkcji. Obserwujemy kolejne komunikaty, w kontekście potencjalnego problemu.

As you wish.

Initializing App Engine resources...done.

Services to deploy:

descriptor:                  [/tmp/tmp.BlDhHB9Nxx/production.yaml]

source:                      [/tmp/tmp.BlDhHB9Nxx]

target project:              [gtm-ph8vxqh-xxxx]

target service:              [default]

target version:              [production]

target url:                  [https://gtm-ph8vxqh-xxxx.uc.r.appspot.com]

target service account:      [App Engine default service account]

Enabling service [appengineflex.googleapis.com] on project [gtm-ph8vxqh-xxxx]...

Operation "operations/acf.p2-716521254761-2779xc5f-098c-49b6-a467-exxxxx" finished successfully.

Beginning deployment of service [default]...

WARNING: Deployment of service [default] will ignore the skip_files field in the configuration file, because the image has already been built.

Updating service [default] (this may take several minutes)...done.

Setting traffic split for service [default]...done.

Deployed service [default] to [https://gtm-ph8vxqh-xxxx.uc.r.appspot.com]

You can stream logs from the command line by running:

  $ gcloud app logs tail -s default

To view your application in the web browser run:

  $ gcloud app browse

Services to deploy:

descriptor:                  [/tmp/tmp.BlDhHxxxx/debug.yaml]

source:                      [/tmp/tmp.BlDhHxxxx]

target project:              [gtm-ph8vxqh-xxxx]

target service:              [debug-server]

target version:              [production]

target url:                  [https://debug-server-dot-gtm-ph8vxqh-xxxx.uc.r.appspot.com]

target service account:      [App Engine default service account]

 

Beginning deployment of service [debug-server]...

Created .gcloudignore file. See `gcloud topic gcloudignore` for details.

╔════════════════════════════════════════════════════════════╗

╠═ Uploading 4 files to Google Cloud Storage                ═╣

╚════════════════════════════════════════════════════════════╝

File upload done.

Updating service [debug-server]...⠹WARNING: *** Improve build performance by generating and committing package-lock.json.

Updating service [debug-server]...done.

Setting traffic split for service [debug-server]...done.

Deployed service [debug-server] to [https://debug-server-dot-gtm-xxxx-xxxx.uc.r.appspot.com]

 

You can stream logs from the command line by running:

  $ gcloud app logs tail -s debug-server

 

To view your application in the web browser run:

  $ gcloud app browse -s debug-server

Configurations to update:

 

descriptor:      [/tmp/tmp.Blxxxx/dispatch.yaml]

type:            [routing rules]

target project:  [gtm-xxxxxx-nzc1n]

 

Waiting for operation [apps/gtm-xxxxxx-nzc1n/operations/03f2xxxc-16fc-4420-xxxx-f0a085abbac2] to complete...done.

Updating config [dispatch]...done.

 

Custom routings have been updated.

Deleting the following versions:

 - gtm-ph8vxqh-xxxx/default/testing

Deleting [default/testing]...done.

 

Your server deployment is complete.

krzysztof_surowiecki@cloudshell:~ (gtm-xxxxxx-xxxx)$

Tym samym nasz kontener serwerowy jest na produkcji => a dane powinny być już widoczne w interfejsie GA (na początku w raportach czasu rzeczywistego).

Pamiętajmy jeszcze o jednej kluczowej rzeczy => monitoring kosztów. Można to prowadzić poprzez panel Google Cloud Platform oraz poprzez system alertów budżetowych, jakie możemy dopisać do naszego konta.