Olá! Meu nome é Dmitry, sou engenheiro de lançamento da equipe Avito CI / CD Speed. Há vários anos, meus colegas e eu somos responsáveis por tudo relacionado aos lançamentos de nossos aplicativos móveis e não só. Da última vez, falei sobre nosso sistema de liberação de aplicativo móvel baseado em contrato. Hoje vamos falar sobre como automatizamos a coleta de informações do Firebase sobre novos erros fatais em aplicativos móveis.
Problemático
. . , .
, , 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. .