02.2023 | Google Tag Manager Server Side | Google Analytics 4 | App Engine
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 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:
Link do dokumentacji:
Zaczynamy zatem.
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.
Przed wykonaniem deployu kontenera GTM do Google Cloud Platform, należy sprawdzić, czy:
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:
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:
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.
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 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 |
|
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 |
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.
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.
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:
Nazwa subdomeny może być wybrana dowolnie, nie ma to wpływu na działanie serwera, a zatem możemy wykorzystać nazwy np.
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:
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.
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:
W tym celu możemy wykorzystać albo:
W naszym przykładzie, implementację GTM Server-Side na stronie analyticslab.biz, oprzemy o kontener 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:
Aby dane ze strony były zbierane, to potrzebujemy teraz skonfigurować tag Google Analytics w ramach naszego kontenera GTM.
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.
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.
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:
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.
Napisz do mnie poprzez formularz kontaktowy.