Beaucoup utilisent des outils spécialisés pour créer des procédures d'extraction, de transformation et de chargement de données dans des bases de données relationnelles. Le processus de travail des outils est enregistré, et les erreurs sont documentées.
En cas d'erreur, le journal contient des informations sur les raisons pour lesquelles l'outil n'a pas rĂ©ussi Ă exĂ©cuter la tĂąche et quels modules (souvent en java) se sont arrĂȘtĂ©s. Dans les derniĂšres lignes, on peut trouver l'erreur de la base de donnĂ©es, par exemple, une violation de clĂ© unique dans la table.
Pour répondre à la question du rÎle des informations d'erreurs ETL, j'ai classé tous les problÚmes survenus au cours des deux derniÚres années dans un grand entrepÎt.

Les erreurs de base de données comprennent des problÚmes tels que le manque d'espace, la rupture de connexion, une session suspendue, etc.
Les erreurs logiques comprennent des problÚmes tels que les violations de clés de table, des objets non valides, l'absence d'accÚs aux objets, etc.
Le planificateur peut ne pas ĂȘtre lancĂ© Ă temps, peut se bloquer, etc.
Les erreurs simples ne nĂ©cessitent pas beaucoup de temps pour ĂȘtre corrigĂ©es. La plupart d'entre elles peuvent ĂȘtre gĂ©rĂ©es automatiquement par un bon ETL.
Les erreurs complexes nécessitent d'ouvrir et de vérifier les procédures de traitement des données, d'explorer les sources de données. Elles entraßnent souvent des tests des modifications et des déploiements.
Ainsi, la moitié de tous les problÚmes est liée à la base de données. 48 % de toutes les erreurs sont des erreurs simples.
Un tiers de tous les problÚmes est lié à des modifications de la logique ou du modÚle de l'entrepÎt, et plus de la moitié de ces erreurs sont complexes.
Moins d'un quart de tous les problÚmes sont liés au planificateur de tùches, dont 18 % sont des erreurs simples.
En général, 22 % des erreurs survenues sont complexes, leur correction nécessite le plus d'attention et de temps. Elles se produisent environ une fois par semaine. Pendant ce temps, les erreurs simples se produisent presque tous les jours.
Il est évident que le suivi des processus ETL sera efficace lorsque le journal indique de maniÚre aussi précise que possible l'emplacement de l'erreur et nécessite un minimum de temps pour localiser la source du problÚme.
Suivi efficace
Qu'aimerais-je voir dans le processus de suivi ETL ?

Start at â quand le travail a commencĂ©,
Source â source de donnĂ©es,
Layer â quel niveau d'entrepĂŽt est chargĂ©,
ETL Job Name â procĂ©dure de chargement, composĂ©e de nombreuses petites Ă©tapes,
Step Number â numĂ©ro de l'Ă©tape actuellement exĂ©cutĂ©e,
Lignes affectĂ©es â combien de donnĂ©es ont dĂ©jĂ Ă©tĂ© traitĂ©es,
DurĂ©e sec â combien de temps cela prend,
Statut â tout va bien ou non : OK, ERREUR, EN COURS, BLOQUĂ
Message â dernier message rĂ©ussi ou description de l'erreur.
Sur la base du statut des enregistrements, il est possible d'envoyer un e-mail aux autres participants. S'il n'y a pas d'erreurs, l'e-mail n'est pas nécessaire.
Ainsi, en cas d'erreur, l'endroit exact oĂč cela s'est produit est clairement indiquĂ©.
Il arrive parfois que l'outil de surveillance lui-mĂȘme ne fonctionne pas. Dans ce cas, il est possible d'appeler directement dans la base de donnĂ©es la vue sur laquelle le rapport est basĂ©.
Table de surveillance ETL
Pour mettre en place la surveillance des processus ETL, une seule table et une seule vue sont suffisantes.
Pour cela, on peut revenir dans et créer un prototype dans une base de données SQLite.
DDL de la table
CREATE TABLE UTL_JOB_STATUS (
/* Table pour l'enregistrement du journal d'exécution des tùches. Important que la tùche ait les étapes ETL_START et ETL_END ou ETL_ERROR */
UTL_JOB_STATUS_ID INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
SID INTEGER NOT NULL DEFAULT -1, /* Identificateur de session. Unique pour chaque Exécution de tùche */
LOG_DT INTEGER NOT NULL DEFAULT 0, /* Date et heure */
LOG_D INTEGER NOT NULL DEFAULT 0, /* Date */
JOB_NAME TEXT NOT NULL DEFAULT 'N/A', /* Nom de la tĂąche comme JOB_STG2DM_GEO */
STEP_NAME TEXT NOT NULL DEFAULT 'N/A', /* ETL_START, ..., ETL_END/ETL_ERROR */
STEP_DESCR TEXT, /* Description de la tĂąche ou message d'erreur */
UNIQUE (SID, JOB_NAME, STEP_NAME)
);
INSERT INTO UTL_JOB_STATUS (UTL_JOB_STATUS_ID) VALUES (-1);DDL de la vue/rapport
CRĂER UNE VUE SI NON EXISTE UTL_JOB_STATUS_V
EN TANT QUE
/* Contenu : Journal d'exécution du package pour les 3 derniers mois. */
AVEC SRC COMME (
SĂLECTIONNER LOG_D,
LOG_DT,
UTL_JOB_STATUS_ID,
SID,
CASE WHEN INSTR(JOB_NAME, 'FTP') THEN 'TRANSFERT' /* transfert de fichier */
WHEN INSTR(JOB_NAME, 'STG') THEN 'STAGE' /* étape */
WHEN INSTR(JOB_NAME, 'CLS') THEN 'NETTOYAGE' /* nettoyage */
WHEN INSTR(JOB_NAME, 'DIM') THEN 'DIMENSION' /* dimension */
WHEN INSTR(JOB_NAME, 'FCT') THEN 'FAIT' /* fait */
WHEN INSTR(JOB_NAME, 'ETL') THEN 'STAGE-MART' /* mart de données */
WHEN INSTR(JOB_NAME, 'RPT') THEN 'RAPPORT' /* rapport */
ELSE 'N/A' END AS COUCHE,
CASE WHEN INSTR(JOB_NAME, 'ACCESS') THEN 'LOG DâACCĂS' /* source */
WHEN INSTR(JOB_NAME, 'MASTER') THEN 'DONNĂES MAĂTRES' /* source */
WHEN INSTR(JOB_NAME, 'AD-HOC') THEN 'AD-HOC' /* source */
ELSE 'N/A' END AS SOURCE,
JOB_NAME,
STEP_NAME,
CASE WHEN STEP_NAME='ETL_START' THEN 1 ELSE 0 END AS START_FLAG,
CASE WHEN STEP_NAME='ETL_END' THEN 1 ELSE 0 END AS END_FLAG,
CASE WHEN STEP_NAME='ETL_ERROR' THEN 1 ELSE 0 END AS ERROR_FLAG,
STEP_NAME || ' : ' || STEP_DESCR AS STEP_LOG,
SUBSTR( SUBSTR(STEP_DESCR, INSTR(STEP_DESCR, '***')+4), 1, INSTR(SUBSTR(STEP_DESCR, INSTR(STEP_DESCR, '***')+4), '***')-2 ) AS AFFECTED_ROWS
DE UTL_JOB_STATUS
OĂ datetime(LOG_D, 'unixepoch') >= date('now', 'start of month', '-3 month')
)
SĂLECTIONNER JB.SID,
JB.MIN_LOG_DT COMME START_DT,
strftime('%d.%m.%Y %H:%M', datetime(JB.MIN_LOG_DT, 'unixepoch')) AS LOG_DT,
JB.SOURCE,
JB.COUCHE,
JB.JOB_NAME,
CASE
QUAND JB.ERROR_FLAG = 1 ALORS 'ERREUR'
QUAND JB.ERROR_FLAG = 0 ET JB.END_FLAG = 0 ET strftime('%s','now') - JB.MIN_LOG_DT > 0.5*60*60 ALORS 'EN ATTENTE' /* une demi-heure */
QUAND JB.ERROR_FLAG = 0 ET JB.END_FLAG = 0 ALORS 'EN COURS'
SINON 'OK'
FIN AS STATUT,
ERR.STEP_LOG AS STEP_LOG,
JB.CNT AS STEP_CNT,
JB.AFFECTED_ROWS AS AFFECTED_ROWS,
strftime('%d.%m.%Y %H:%M', datetime(JB.MIN_LOG_DT, 'unixepoch')) AS JOB_START_DT,
strftime('%d.%m.%Y %H:%M', datetime(JB.MAX_LOG_DT, 'unixepoch')) AS JOB_END_DT,
JB.MAX_LOG_DT - JB.MIN_LOG_DT AS JOB_DURATION_SEC
DE
( SĂLECTIONNER SID, SOURCE, COUCHE, JOB_NAME,
MAX(UTL_JOB_STATUS_ID) COMME UTL_JOB_STATUS_ID,
MAX(START_FLAG) COMME START_FLAG,
MAX(END_FLAG) COMME END_FLAG,
MAX(ERROR_FLAG) COMME ERROR_FLAG,
MIN(LOG_DT) COMME MIN_LOG_DT,
MAX(LOG_DT) COMME MAX_LOG_DT,
SOMME(1) COMME CNT,
SOMME(IFNULL(AFFECTED_ROWS, 0)) COMME AFFECTED_ROWS
DE SRC
GROUPE PAR SID, SOURCE, COUCHE, JOB_NAME
) JB,
( SĂLECTIONNER UTL_JOB_STATUS_ID, SID, JOB_NAME, STEP_LOG
DE SRC
OĂ 1 = 1
) ERR
OĂ 1 = 1
ET JB.SID = ERR.SID
ET JB.JOB_NAME = ERR.JOB_NAME
ET JB.UTL_JOB_STATUS_ID = ERR.UTL_JOB_STATUS_ID
ORDER BY JB.MIN_LOG_DT DESC, JB.SID DESC, JB.SOURCE;Vérification SQL de la possibilité d'obtenir un nouveau numéro de session
SĂLECTIONNER SOMME (
CASE QUAND start_job.JOB_NAME EST NON NULL ET end_job.JOB_NAME EST NULL /* emploi existant terminé */
ET NON ( 'y' = 'n' ) /* redĂ©marrer de force PARAMĂTRE */
ALORS 1 SINON 0
FIN ) COMME IS_RUNNING
DE
( SĂLECTIONNER 1 COMME dummy DE UTL_JOB_STATUS OĂ sid = -1) d_job
JOINDRE EXTĂRIEUR GAUCHE
( SĂLECTIONNER JOB_NAME, SID, 1 COMME dummy
DE UTL_JOB_STATUS
OĂ JOB_NAME = 'RPT_ACCESS_LOG' /* nom de job PARAMĂTRE */
ET STEP_NAME = 'ETL_START'
GROUPE PAR JOB_NAME, SID
) start_job /* démarre */
SUR d_job.dummy = start_job.dummy
JOINDRE EXTĂRIEUR GAUCHE
( SĂLECTIONNER JOB_NAME, SID
DE UTL_JOB_STATUS
OĂ JOB_NAME = 'RPT_ACCESS_LOG' /* nom de job PARAMĂTRE */
ET STEP_NAME IN ('ETL_END', 'ETL_ERROR') /* statut d'arrĂȘt */
GROUPE PAR JOB_NAME, SID
) end_job /* termine */
SUR start_job.JOB_NAME = end_job.JOB_NAME
ET start_job.SID = end_job.SIDCaractéristiques de la table :
- Le dĂ©but et la fin de la procĂ©dure de traitement des donnĂ©es doivent ĂȘtre accompagnĂ©s des Ă©tapes ETL_START et ETL_END
- En cas d'erreur, une Ă©tape ETL_ERROR doit ĂȘtre créée avec sa description
- Le nombre de donnĂ©es traitĂ©es doit ĂȘtre mis en Ă©vidence, par exemple, par des astĂ©risques
- La mĂȘme procĂ©dure peut ĂȘtre lancĂ©e simultanĂ©ment avec le paramĂštre force_restart=y, sans cela, le numĂ©ro de session n'est fourni qu'Ă la procĂ©dure terminĂ©e
- En mode normal, il n'est pas possible de lancer simultanĂ©ment la mĂȘme procĂ©dure de traitement des donnĂ©es
Les opérations nécessaires pour travailler avec la table sont les suivantes :
- Obtenir le numéro de session de la procédure ETL en cours d'exécution
- Insérer un enregistrement de log dans la table
- Obtenir le dernier enregistrement réussi de la procédure ETL
Dans des bases de donnĂ©es comme Oracle ou Postgres, ces opĂ©rations peuvent ĂȘtre rĂ©alisĂ©es Ă l'aide de fonctions intĂ©grĂ©es. Pour SQLite, un mĂ©canisme externe est nĂ©cessaire et dans ce cas, il .
Sortie
Ainsi, les messages d'erreur dans les outils de traitement des données jouent un rÎle méga-important. Mais il est difficile de les qualifier d'optimaux pour une recherche rapide de la cause du problÚme. Lorsque le nombre de procédures approche la centaine, la surveillance des processus devient un projet complexe.
L'article présente un exemple d'une possible solution au problÚme sous la forme d'un prototype. L'ensemble du prototype d'un petit entrepÎt est disponible sur GitLab .
Source : habr.com
