Hallo! Mein Name ist Dmitry, ich bin Release-Ingenieur im Avito CI / CD Speed-Team. Seit einigen Jahren sind meine Kollegen und ich für alles verantwortlich, was mit der Veröffentlichung unserer mobilen Anwendungen zu tun hat, und nicht nur. Das letzte Mal habe ich über unser vertragsbasiertes Release-System für mobile Anwendungen gesprochen. Heute werden wir darüber sprechen, wie wir die Erfassung von Informationen aus Firebase über neue schwerwiegende Fehler in mobilen Anwendungen automatisiert haben.

. . , .
, , Fabric, vadimsmal YourDestiny Fabricio. , Jira- , Git-Blame c -.
Google Fabric, Firebase, .
, . , Firebase API , .
Google Cloud Functions
, — .
Firebase Google Cloud Functions . serverless FaaS Google, Google. Firebase-Crashlytics ( deprecated). call-back crashlytics- . — “onNew”( crashlytics) “onVelocityAlert” ( crashlytics).

. Firebase-Google Cloud Functions, , . , JS Google Cloud:
const functions = require('firebase-functions');
const rp = require('request-promise');
function sendEvent(event) {
return rp({
method: 'POST',
uri: functions.config().crashlytics.crash_collector_url,
body: event,
json: true,
});
}
exports.NewIssueEvent = functions.crashlytics.issue().onNew(async (issue) => {
await processEvent(issue, 'NewIssueEvent')
});
exports.RegressedEvent = functions.crashlytics.issue().onRegressed(async (issue) => {await processEvent(issue, 'RegressedEvent')});
exports.VelocityAlertEvent = functions.crashlytics.issue().onVelocityAlert(async (issue) => {await processEvent(issue, 'VelocityAlertEvent')});
const processEvent = async (event, type) =>{
if (isActualEvent(event)) {
await sendEvent(event);
console.log(`Posted ${type} ${event.issueId} successfully to crash collector`);
}
else{
console.log(`It's old event or not Avito. Do nothing`);
}
}
const isActualEvent = (event) =>{
const {appInfo} = event;
const {appName, latestAppVersion} = appInfo;
const version = latestAppVersion && parseFloat(latestAppVersion.split(' ')[0]);
console.log(`Event appName: ${appName} version: ${version}`);
return appName === 'Avito' && version > 60.0
}
, , , .
. Firebase-Crashlytics fatal ( -) non-fatal ( crashlytics). “onNew” , - , .
BigQuery
Google Firebase BigQuery. BigQuery — , . 2019 c Firebase — Batch Table.
:
- , , .
- — fatal non-fatal.
- , ( ) .
:

BigQuery : , . BigQuery , . — 17:00, Firebase-Crashlytics BigQuery , :
SELECT issue_id, is_fatal, COUNT(*) as crashes_counter,
COUNT(DISTINCT installation_uuid) AS affected_users
FROM `android.firebase_crashlytics.{table}`
WHERE issue_id in ( {issues_id_string} )
GROUP BY issue_id, is_fatal
LIMIT 1000
, . , , , - “onVelocityAlert” Google Cloud Function. , N . “onVelocityAlert” , Google, , .
«» , . VelocityAlert Firebase-Crashlytics . Firebase -, VelocityAlert. , . , , . .
VelocityAlert . , VelocityAlert .
:

. .
, Fabric :
- Git-Blame.
- .
- -.
— Git-Blame. , Jira, , Git-Blame , . , .
Nupokati. , BigQuery, — — daily report .
daily report
, . , , , .
daily report VelocityAlert - . , , .

Google Cloud Functions
. , Firebase . , Firebase-crashlytics Google Cloud Functions deprecated 1 2020 . . .

Cloud Functions BigQuery. : daily report, velocityAlerts, -. .
SELECT
issue_id,
issue_title,
is_fatal,
COUNT(issue_id) as crashes_counter,
ARRAY_AGG (distinct application.display_version) AS versions,
COUNT(DISTINCT installation_uuid) AS affected_users
FROM `android.firebase_crashlytics.{table}`
WHERE is_fatal=true
GROUP BY issue_title, issue_id, is_fatal
HAVING ARRAY_LENGTH(versions)=1 AND "{version}" in UNNEST(versions)
ORDER BY crashes_counter DESC
. Firebase . . BigQuery , .
, :
- BigQuery , , .
- BigQuery. , .
- BigQuery , . .
- BigQuery streaming. .
- Google Cloud Platform. .