Observação:
- Este tutorial requer acesso ao Oracle Cloud. Para se inscrever e obter uma conta grátis, consulte Conceitos Básicos do Oracle Cloud Infrastructure Free Tier.
- Ele usa valores de exemplo para credenciais, tenancy e compartimentos do Oracle Cloud Infrastructure. Ao concluir seu laboratório, substitua esses valores por valores específicos do seu ambiente de nuvem.
Publique métricas personalizadas do Oracle Autonomous Database usando o serviço Oracle Cloud Infrastructure Monitoring
Introdução
O Oracle Autonomous Database está revolucionando como os dados são gerenciados com a introdução do primeiro banco de dados "autônomo" do mundo. O Oracle Autonomous Database está capacitando aplicativos comerciais críticos de empresas de todo o mundo, como sua principal fonte de dados.
O Oracle Autonomous Database oferece muitas métricas de serviço relacionadas ao banco de dados importantes prontas para uso, graças a sua integração profunda com o serviço de Monitoramento do Oracle Cloud Infrastructure (OCI). Dito isto, muitos dos nossos clientes inovadores querem dar um passo à sua jornada de observabilidade. Esses clientes querem coletar, publicar e analisar suas próprias métricas sobre os dados dos aplicativos armazenados no Oracle Autonomous Database. Chamamos essas métricas personalizadas e elas são as métricas que os aplicativos podem coletar e postar no serviço OCI Monitoring por uma API REST simples fornecida pelo OCI SDK.
Este tutorial mostra a facilidade com que você pode publicar métricas personalizadas do seu Oracle Autonomous Database com apenas alguns scripts PL/SQL e alguns cliques na Console do Oracle Cloud.
Este tutorial usa um esquema de banco de dados de ordens de compra de eCommerce como exemplo para mostrar como você pode calcular e coletar métricas de dados. Você verá como calcular periodicamente uma métrica que representa a contagem de cada status do pedido (preenchido, aceito, rejeitado etc.) para cada pedido recebido pelo aplicativo de ecommerce. E, por fim, você publicará essas métricas personalizadas no Oracle Cloud Monitoring Service.
Pré-requisitos
- Acesso a uma camada grátis ou conta paga do Oracle Cloud.
-
Qualquer tipo de instância do Oracle Autonomous Database, compartilhada ou dedicada.
Observação: Para este tutorial, você usa um Oracle Autonomous Database para uma instância do Oracle Autonomous Transaction Processing com apenas 1 OCPU e 1 TB de armazenamento em infraestrutura compartilhada. Você pode criar isso usando uma conta na camada gratuita do Oracle Cloud.
- Familiaridade básica com PL/SQL.
- Familiaridade da Console do Oracle Cloud.
- É possível usar qualquer um dos clientes do Oracle Database, como SQL Developer ou SQL*Plus. Se você for iniciante no Oracle Autonomous Transaction Processing, consulte Conexão com um Autonomous Database. Para o Oracle Autonomous Transaction Processing, consulte SQL Developer Web, disponível na página Console do Oracle Cloud para o Oracle Autonomous Transaction Processing. Não há necessidade do Oracle Wallet ao usar o SQL Developer Web.
- Acesso do usuário
ADMIN
à sua instância do Oracle Autonomous Transaction Processing. - Familiaridade básica com conceitos do Oracle Cloud, como o serviço OCI Monitoring, PostMetricData API para publicar métricas personalizadas e grupos dinâmicos e princípios de recursos.
Visão Geral da Solução
Teremos um script PL/SQL simples implantado em nossa instância do Oracle Autonomous Database, que é programado para ser executado periodicamente para calcular, coletar e postar as métricas personalizadas no serviço de Monitoramento do OCI.
Além disso, a instância do Oracle Autonomous Database pode ter um ponto final privado ou público. A comunicação entre o Oracle Autonomous Database e o serviço de Monitoramento do OCI ocorre na rede do Oracle Cloud, que é ultrarrápida e altamente disponível. Não há necessidade de configurar um gateway de serviço.
Neste tutorial, abrangeremos tudo o que você precisa saber até que precise obter as métricas personalizadas do Oracle Autonomous Database para o serviço de Monitoramento do OCI.
Visão Geral
- Crie um grupo dinâmico para sua instância do Oracle Autonomous Transaction Processing e autorize-o a publicar métricas no serviço de Monitoramento do Oracle Cloud Infrastructure (OCI) com uma política.
- Crie um novo usuário ou esquema de banco de dados com os privilégios necessários na sua instância do Oracle Autonomous Transaction Processing ou atualize o usuário ou esquema de banco de dados existente com os privilégios necessários.
- Crie uma tabela chamada
SHOPPING_ORDER
para armazenar dados do nosso aplicativo de ecommerce de exemplo (você calcula métricas personalizadas nos pedidos de clientes armazenados nessa tabela). - Defina o script PL/SQL para preencher dados aleatórios de ordens de cliente na tabela
SHOPPING_ORDER
. - Defina o script PL/SQL para calcular, coletar e armazenar no buffer e publicar as métricas personalizadas no serviço OCI Monitoring.
- Programe e execute scripts das etapas 4 e 5.
- Observe as métricas personalizadas publicadas no Oracle Cloud Console.
Em um caso de uso de produção, você tem seu próprio aplicativo para preencher os dados e as atualizações do mundo real. Assim, as etapas 3 e 4 não serão necessárias neste caso.
Etapas
-
Crie um grupo dinâmico para sua instância do Oracle Autonomous Transaction Processing e autorize-o a publicar métricas no serviço de Monitoramento do Oracle Cloud Infrastructure (OCI) com a política.
-
Crie um grupo dinâmico chamado
adb_dg
para sua instância (ou instâncias) do Oracle Autonomous Transaction Processing, com a regra:ALL {resource.type = 'autonomousdatabase', resource.compartment.id = '<compartment OCID for your ADB instance>'}
Como alternativa, você pode selecionar uma única instância do Oracle Autonomous Transaction Processing, em vez de todas as instâncias do compartimento:
ALL {resource.type = 'autonomousdatabase', resource.id = '<OCID for your ATP instance>'}
-
Crie uma política do Oracle Cloud Infrastructure Identity and Access Management (IAM) para autorizar o grupo dinâmico
adb_dg
a publicar métricas no serviço OCI Monitoring com uma política chamadaadb_dg_policy
e com regras de políticaAllow dynamic-group adb_dg to read metrics in compartment <Your Oracle Autonomous Transaction Processing compartment OCID>
.Agora o seu serviço Oracle Autonomous Transaction Processing (coberto pela definição do seu grupo dinâmico
adb_dg
) está autorizado a publicar métricas no mesmo compartimento.Você não tem usuários de banco de dados do Oracle Autonomous Transaction Processing autorizados a publicar métricas no serviço OCI Monitoring sim. A PL/SQL executada no Oracle Autonomous Transaction Processing ainda não consegue postar nenhuma métrica no serviço de Monitoramento do OCI. Você fará isso na Etapa 3c.
-
-
Crie um novo usuário ou esquema de banco de dados com os privilégios necessários na sua instância do Oracle Autonomous Transaction Processing ou atualize um usuário ou esquema de banco de dados existente com os privilégios necessários.
-
Crie um usuário ou esquema de banco de dados chamado
ECOMMERCE_USER
em sua instância do Oracle Autonomous Transaction Processing. Você pode criar isso como um usuário ADMIN para cada instância do Oracle Autonomous Transaction Processing. Você poderá ignorar essa etapa se optar por usar um usuário existente.CREATE USER ECOMMERCE_USER IDENTIFIED BY "Password of your choice for this User";
Observação: Agora vamos fazer referência ao usuário (ou esquema) pois
ECOMMERCE_USER
e o restante das etapas permanece o mesmo, quer você use um usuário existente ou um usuário recém-criado. -
Conceda privilégios obrigatórios relacionados ao Oracle Database ao
ECOMMERCE_USER
.GRANT CREATE TABLE, ALTER ANY INDEX, CREATE PROCEDURE, CREATE JOB, SELECT ANY TABLE, EXECUTE ANY PROCEDURE, UPDATE ANY TABLE, CREATE SESSION, UNLIMITED TABLESPACE, CONNECT, RESOURCE TO ECOMMERCE_USER; GRANT SELECT ON "SYS"."V_$PDBS" TO ECOMMERCE_USER; GRANT EXECUTE ON "C##CLOUD$SERVICE"."DBMS_CLOUD" to ECOMMERCE_USER; GRANT SELECT ON SYS.DBA_JOBS_RUNNING TO ECOMMERCE_USER;
-
Ative as credenciais do Oracle Database para o Principal do Recurso do Oracle Cloud e dê seu acesso ao usuário db
ECOMMERCE_USER
. Isso conecta o grupo dinâmicoadb_dg
criado na etapa 1 ao usuário do banco de dadosECOMMERCE_USER
, dando ao usuário a autorização para publicar métricas no serviço OCI Monitoring. Para obter mais informações, consulte Usar Principal de Recurso para Acessar Recursos do Oracle Cloud Infrastructure.EXEC DBMS_CLOUD_ADMIN.ENABLE_RESOURCE_PRINCIPAL(username => 'ECOMMERCE_USER');
-
(Opcional) Verifique as operações concluídas na etapa anterior.
Observação: Quando a credencial do Oracle Database para o Principal do Recurso do Oracle Cloud estiver ativada, ela sempre pertencerá ao usuário ADMIN para o Oracle Autonomous Database. Você pode verificar isso:
SELECT OWNER, CREDENTIAL_NAME FROM DBA_CREDENTIALS WHERE CREDENTIAL_NAME = 'OCI$RESOURCE_PRINCIPAL' AND OWNER = 'ADMIN'; -- To check if any other user, here ECOMMERCE_USER has access DB credential(hence to OCI Resource Principal), you have to check *DBA_TAB_PRIVS* view, as follows. SELECT * from DBA_TAB_PRIVS WHERE DBA_TAB_PRIVS.GRANTEE='ECOMMERCE_USER';
-
-
Crie uma tabela de dados de exemplo chamada
SHOPPING_ORDER
para mostrar o cálculo de métricas em uma tabela de banco de dados.O esquema da tabela é autoexplicativo, mas observe a coluna
STATUS
:DROP TABLE SHOPPING_ORDER; CREATE TABLE SHOPPING_ORDER ( ID NUMBER GENERATED BY DEFAULT ON NULL AS IDENTITY PRIMARY KEY, CREATED_DATE TIMESTAMP(6) DEFAULT CURRENT_TIMESTAMP, DETAILS VARCHAR2(1000) DEFAULT NULL, LAST_UPDATED_DATE TIMESTAMP(6) DEFAULT CURRENT_TIMESTAMP, STATUS VARCHAR2(30 CHAR), TOTAL_CHARGES FLOAT DEFAULT 0.0, CUSTOMER_ID NUMBER(19) ) PARTITION BY LIST ( STATUS ) ( PARTITION ACCEPTED VALUES ( 'ACCEPTED' ), PARTITION PAYMENT_REJECTED VALUES ( 'PAYMENT_REJECTED' ), PARTITION SHIPPED VALUES ( 'SHIPPED' ), PARTITION ABORTED VALUES ( 'ABORTED' ), PARTITION OUT_FOR_DELIVERY VALUES ( 'OUT_FOR_DELIVERY' ), PARTITION ORDER_DROPPED_NO_INVENTORY VALUES ( 'ORDER_DROPPED_NO_INVENTORY' ), PARTITION PROCESSED VALUES ( 'PROCESSED' ), PARTITION NOT_FULLFILLED VALUES ( 'NOT_FULFILLED' ) ); / -- we move rows from one partition to another, hence we enable row movement for this partioned table ALTER TABLE SHOPPING_ORDER ENABLE ROW MOVEMENT;
Cada ordem de compra pode ter qualquer um dos oito valores de status durante sua vida útil:
[ACCEPTED, PAYMENT_REJECTED, SHIPPED, ABORTED, OUT_FOR_DELIVERY, ORDER_DROPPED_NO_INVENTORY, PROCESSED, NOT_FULFILLED]
. -
Leia o script PL/SQL a seguir; ele preenche dados na tabela
SHOPPING_ORDER
. Execute-o no cliente Oracle Database de sua escolha.O script primeiro adicionará o número
TOTAL_ROWS_IN_SHOPPING_ORDER
de linhas à tabelaSHOPPING_ORDER
com dados de ordem gerados aleatoriamente. Em seguida, ele atualizará os dados, alterando aleatoriamente os valores deSTATUS
de cada linhaSHOPPING_ORDER
.CREATE OR REPLACE PROCEDURE POPULATE_DATA_FEED IS ARR_STATUS_RANDOM_INDEX INTEGER; CUSTOMER_ID_RANDOM INTEGER; TYPE STATUS_ARRAY IS VARRAY(8) OF VARCHAR2(30); ARRAY STATUS_ARRAY := STATUS_ARRAY('ACCEPTED', 'PAYMENT_REJECTED', 'SHIPPED', 'ABORTED', 'OUT_FOR_DELIVERY', 'ORDER_DROPPED_NO_INVENTORY', 'PROCESSED', 'NOT_FULFILLED'); TOTAL_ROWS_IN_SHOPPING_ORDER INTEGER := 15000; TYPE ROWID_NT IS TABLE OF ROWID; ROWIDS ROWID_NT; BEGIN -- starting from scratch just be idempotent and have predictable execution time for this stored procedure -- deleting existing rows is optional DELETE SHOPPING_ORDER; -- insert data FOR COUNTER IN 1..TOTAL_ROWS_IN_SHOPPING_ORDER LOOP ARR_STATUS_RANDOM_INDEX := TRUNC(DBMS_RANDOM.VALUE(LOW => 1, HIGH => 9)); CUSTOMER_ID_RANDOM := TRUNC(DBMS_RANDOM.VALUE(LOW => 1, HIGH => 8000)); INSERT INTO SHOPPING_ORDER (STATUS,CUSTOMER_ID) VALUES (ARRAY(ARR_STATUS_RANDOM_INDEX),CUSTOMER_ID_RANDOM); COMMIT; END LOOP; DBMS_OUTPUT.PUT_LINE('DONE WITH INITIAL DATA LOAD'); -- keep on updating the same data FOR COUNTER IN 1..8000 LOOP --Get the rowids SELECT R BULK COLLECT INTO ROWIDS FROM (SELECT ROWID R FROM SHOPPING_ORDER SAMPLE ( 5 ) ORDER BY DBMS_RANDOM.VALUE) RNDM WHERE ROWNUM < TOTAL_ROWS_IN_SHOPPING_ORDER + 1; --update the table ARR_STATUS_RANDOM_INDEX := TRUNC(DBMS_RANDOM.VALUE(LOW => 1, HIGH => 9)); FOR I IN 1..ROWIDS.COUNT LOOP UPDATE SHOPPING_ORDER SET STATUS = ARRAY(ARR_STATUS_RANDOM_INDEX) WHERE ROWID = ROWIDS(I); COMMIT; END LOOP; --sleep in-between if you want to run script for longer duration --DBMS_SESSION.SLEEP(ROUND(dbms_random.value(low => 1, high => 2))); END LOOP; DBMS_OUTPUT.PUT_LINE('DONE WITH POPULATE_DATA_FEED'); EXECUTE IMMEDIATE 'ANALYZE TABLE SHOPPING_ORDER COMPUTE STATISTICS'; END; /
-
Vamos mergulhar no básico real deste tutorial: o script que calcula as métricas personalizadas e as publica no serviço de Monitoramento do OCI. Execute-o no cliente do Oracle Datbase de sua escolha. O script é idempotente para garantir que você pode jogar com ele em várias execuções. Agora, analise o script fragmentado.
-
Crie a tabela
SHOPPING_ORDER_METRICS_TABLE
e use-a para coletar e armazenar em buffer métricas calculadas.Certifique-se de que suas tabelas de dados sejam otimizadas para consultas que executam o cálculo de métricas. Você não deseja que essas consultas sobrecarregem muito seu banco de dados, incomodando seus casos de uso de produção.
DECLARE COUNT_VAR NUMBER := 0; BEGIN SELECT COUNT(*) INTO COUNT_VAR FROM ALL_TABLES WHERE TABLE_NAME = 'SHOPPING_ORDER_METRICS_TABLE'; IF COUNT_VAR > 0 THEN DBMS_OUTPUT.PUT_LINE('TABLE EXISTS ALREADY!'); ELSE -- table doesn't exist EXECUTE IMMEDIATE 'CREATE TABLE SHOPPING_ORDER_METRICS_TABLE( ID NUMBER GENERATED BY DEFAULT ON NULL AS IDENTITY PRIMARY KEY, CREATED_DATE TIMESTAMP(6) DEFAULT CURRENT_TIMESTAMP, STATUS VARCHAR2(30 CHAR), COUNT NUMBER)'; END IF; END; /
-
Crie um procedimento armazenado que calcule a métrica: Contagem do número de ordens por valores de status, na instância de momento dessa coleta de métricas.
O procedimento armazenado em seguida coloca em buffer as métricas calculadas na tabela de buffer
SHOPPING_ORDER_METRICS_TABLE
que você criou na etapa anterior. Buffer para certificar-se de que você possa tentar publicar as métricas novamente no futuro se houver uma interrupção temporária ao publicá-las no serviço de Monitoramento do OCI.CREATE OR REPLACE PROCEDURE COMPUTE_AND_BUFFER_METRICS IS BEGIN -- compute simple metric for getting count order by order-status -- and store in buffer table SHOPPING_ORDER_METRICS_TABLE INSERT INTO SHOPPING_ORDER_METRICS_TABLE (STATUS, COUNT, CREATED_DATE) SELECT STATUS, COUNT(*), SYSTIMESTAMP AT TIME ZONE 'UTC' FROM SHOPPING_ORDER SO GROUP BY SO.STATUS; -- we buffer at most 1000 metric points, please configure as per your needs DELETE FROM SHOPPING_ORDER_METRICS_TABLE SOMT WHERE SOMT.ID NOT IN (SELECT ID FROM SHOPPING_ORDER_METRICS_TABLE ORDER BY CREATED_DATE FETCH FIRST 1000 ROWS ONLY); COMMIT; DBMS_OUTPUT.PUT_LINE('compute and buffering done @ ' || TO_CHAR(SYSTIMESTAMP)); END; /
Para limitar o tamanho da tabela de buffer, corte-a se seu tamanho exceder 1.000 linhas.
-
Use a função PL/SQL
PREPARE_JSON_OBJECT_FROM_METRIC_ROWS
que converte métricas armazenadas em buffer deSHOPPING_ORDER_METRICS_TABLE
em objetos JSON que a API PostMetricsData espera em sua solicitação.Observação:
- Essa função converte o número
BATCH_SIZE_FOR_EACH_POST
dos pontos de dados de métricas mais recentes deSHOPPING_ORDER_METRICS_TABLE
emOCI_METADATA_JSON_OBJ JSON_OBJECT_T
. OCI_METADATA_JSON_OBJ
é uma variável do tipo de dados JSON incorporado PL/SQLJSON_OBJECT_T
. ConstruímosOCI_METADATA_JSON_OBJ
com a mesma estrutura JSON, conforme descrito em PostMetricDataDetails, o corpo da solicitação da API PostMetricsData.
CREATE OR REPLACE FUNCTION GET_METRIC_DATA_DETAILS_JSON_OBJ ( IN_ORDER_STATUS IN VARCHAR2, IN_METRIC_CMPT_ID IN VARCHAR2, IN_ADB_NAME IN VARCHAR2, IN_METRIC_VALUE IN NUMBER, IN_TS_METRIC_COLLECTION IN VARCHAR2 ) RETURN JSON_OBJECT_T IS METRIC_DATA_DETAILS JSON_OBJECT_T; MDD_METADATA JSON_OBJECT_T; MDD_DIMENSIONS JSON_OBJECT_T; ARR_MDD_DATAPOINT JSON_ARRAY_T; MDD_DATAPOINT JSON_OBJECT_T; BEGIN MDD_METADATA := JSON_OBJECT_T(); MDD_METADATA.PUT('unit', 'row_count'); -- metric unit is arbitrary, as per choice of developer MDD_DIMENSIONS := JSON_OBJECT_T(); MDD_DIMENSIONS.PUT('dbname', IN_ADB_NAME); MDD_DIMENSIONS.PUT('schema_name', SYS_CONTEXT('USERENV', 'CURRENT_SCHEMA')); MDD_DIMENSIONS.PUT('table_name', 'SHOPPING_ORDER'); MDD_DIMENSIONS.PUT('status_enum', IN_ORDER_STATUS); MDD_DATAPOINT := JSON_OBJECT_T(); MDD_DATAPOINT.PUT('timestamp', IN_TS_METRIC_COLLECTION); --timestamp value RFC3339 compliant MDD_DATAPOINT.PUT('value', IN_METRIC_VALUE); MDD_DATAPOINT.PUT('count', 1); ARR_MDD_DATAPOINT := JSON_ARRAY_T(); ARR_MDD_DATAPOINT.APPEND(MDD_DATAPOINT); METRIC_DATA_DETAILS := JSON_OBJECT_T(); METRIC_DATA_DETAILS.PUT('datapoints', ARR_MDD_DATAPOINT); METRIC_DATA_DETAILS.PUT('metadata', MDD_METADATA); METRIC_DATA_DETAILS.PUT('dimensions', MDD_DIMENSIONS); -- namespace, resourceGroup and name for the custom metric are arbitrary values, as per choice of developer METRIC_DATA_DETAILS.PUT('namespace', 'custom_metrics_from_adb'); METRIC_DATA_DETAILS.PUT('resourceGroup', 'ecommerece_adb'); METRIC_DATA_DETAILS.PUT('name', 'customer_orders_submitted'); -- since compartment OCID is fetched using ADB metadata, our custom metrics will land up in same compartment as our ADB METRIC_DATA_DETAILS.PUT('compartmentId', IN_METRIC_CMPT_ID); RETURN METRIC_DATA_DETAILS; END; / CREATE OR REPLACE FUNCTION PREPARE_JSON_OBJECT_FROM_METRIC_ROWS ( OCI_METADATA_JSON_OBJ JSON_OBJECT_T, BATCH_SIZE_FOR_EACH_POST NUMBER ) RETURN JSON_OBJECT_T IS OCI_POST_METRICS_BODY_JSON_OBJ JSON_OBJECT_T; ARR_METRIC_DATA JSON_ARRAY_T; METRIC_DATA_DETAILS JSON_OBJECT_T; BEGIN -- prepare JSON body for postmetrics api.. -- for details please refer https://docs.oracle.com/en-us/iaas/api/#/en/monitoring/20180401/datatypes/PostMetricDataDetails ARR_METRIC_DATA := JSON_ARRAY_T(); -- PostMetrics api has soft limit of 50 unique metric stream per call, hence we cap it at 50. -- For Production usecase where every metric data point is important, we can use chunking FOR METRIC_ROW IN (SELECT * FROM SHOPPING_ORDER_METRICS_TABLE ORDER BY CREATED_DATE DESC FETCH FIRST BATCH_SIZE_FOR_EACH_POST ROWS ONLY) LOOP --DBMS_OUTPUT.PUT_LINE('inside for loop ' || METRIC_ROW.STATUS ); METRIC_DATA_DETAILS := GET_METRIC_DATA_DETAILS_JSON_OBJ( METRIC_ROW.STATUS, OCI_METADATA_JSON_OBJ.GET_STRING('COMPARTMENT_OCID'), OCI_METADATA_JSON_OBJ.GET_STRING('DATABASE_NAME'), METRIC_ROW.COUNT, TO_CHAR(METRIC_ROW.CREATED_DATE, 'yyyy-mm-dd"T"hh24:mi:ss.ff3"Z"')); --DBMS_OUTPUT.PUT_LINE('METRIC_DATA_DETAILS '|| METRIC_DATA_DETAILS.to_clob); ARR_METRIC_DATA.APPEND(METRIC_DATA_DETAILS); END LOOP; DBMS_OUTPUT.PUT_LINE('done with for loop '); OCI_POST_METRICS_BODY_JSON_OBJ := JSON_OBJECT_T(); OCI_POST_METRICS_BODY_JSON_OBJ.PUT('metricData', ARR_METRIC_DATA); RETURN OCI_POST_METRICS_BODY_JSON_OBJ; END; /
- Essa função converte o número
-
Use o código PL/SQL para publicar essas métricas convertidas no serviço OCI Monitoring usando a API PostMetricsData.
Observação: Conseguimos isso com a função PL/SQL denominada
POST_METRICS_DATA_TO_OCI
e o procedimento armazenadoPUBLISH_BUFFERED_METRICS_TO_OCI
.CREATE OR REPLACE FUNCTION POST_METRICS_DATA_TO_OCI(OCI_POST_METRICS_BODY_JSON_OBJ JSON_OBJECT_T, ADB_REGION VARCHAR2) RETURN NUMBER IS RETRY_COUNT INTEGER := 0; MAX_RETRIES INTEGER := 3; RESP DBMS_CLOUD_TYPES.RESP; EXCEPTION_POSTING_METRICS EXCEPTION; SLEEP_IN_SECONDS INTEGER := 5; BEGIN FOR RETRY_COUNT in 1..MAX_RETRIES LOOP -- invoking REST endpoint for OCI Monitoring API -- for details please refer https://docs.oracle.com/en-us/iaas/api/#/en/monitoring/20180401/MetricData/PostMetricData RESP := DBMS_CLOUD.SEND_REQUEST(CREDENTIAL_NAME => 'OCI$RESOURCE_PRINCIPAL', URI => 'https://telemetry-ingestion.'|| ADB_REGION|| '.oraclecloud.com/20180401/metrics', METHOD =>DBMS_CLOUD.METHOD_POST, BODY => UTL_RAW.CAST_TO_RAW(OCI_POST_METRICS_BODY_JSON_OBJ.TO_STRING)); IF DBMS_CLOUD.GET_RESPONSE_STATUS_CODE(RESP) = 200 THEN -- when it is 200 from OCI Metrics API, all good DBMS_OUTPUT.PUT_LINE('POSTED METRICS SUCCESSFULLY TO OCI MONIOTRING'); RETURN 200; ELSIF DBMS_CLOUD.GET_RESPONSE_STATUS_CODE(RESP) = 429 THEN -- 429 is caused by throttling IF RETRY_COUNT < MAX_RETRIES THEN -- increase sleep time for each retry, doing exponential backoff DBMS_SESSION.SLEEP(POWER(SLEEP_IN_SECONDS, RETRY_COUNT+1)); DBMS_OUTPUT.PUT_LINE('RETRYING THE POSTMETRICS API CALL'); ELSE DBMS_OUTPUT.PUT_LINE('ABANDONING POSTMETRICS CALLS, AFTER 3 RETRIES, CAUSED BY THROTTLING, WILL BERETRIED IN NEXT SCHEDULED RUN'); RETURN 429; END IF; ELSE -- for any other http status code....1. log error, 2. raise exception and then quit posting metrics, as it is most probably a persistent error DBMS_OUTPUT.PUT_LINE('IRRECOVERABLE ERROR HAPPENED WHEN POSTING METRICS TO OCI MONITORING, PLEASE SEE CONSOLE FOR ERRORS'); -- Response Body in TEXT format DBMS_OUTPUT.put_line('Body: ' || '------------' || CHR(10) || DBMS_CLOUD.get_response_text(resp) || CHR(10)); -- Response Headers in JSON format DBMS_OUTPUT.put_line('Headers: ' || CHR(10) || '------------' || CHR(10) || DBMS_CLOUD.get_response_headers(resp).to_clob || CHR(10)); -- Response Status Code DBMS_OUTPUT.put_line('Status Code: ' || CHR(10) || '------------' || CHR(10) || DBMS_CLOUD.get_response_status_code(resp)); RETURN 500; END IF; END LOOP; END; / CREATE OR REPLACE PROCEDURE PUBLISH_BUFFERED_METRICS_TO_OCI IS OCI_METADATA_JSON_RESULT VARCHAR2(1000); OCI_METADATA_JSON_OBJ JSON_OBJECT_T; ADB_REGION VARCHAR2(25); OCI_POST_METRICS_BODY_JSON_OBJ JSON_OBJECT_T; TYPE ID_ARRAY IS VARRAY(50) OF NUMBER; ARRAY ID_ARRAY; TOTAL_METRICS_STREAM_CNT NUMBER; HTTP_CODE NUMBER; BATCH_SIZE_FOR_EACH_POST NUMBER:=8; -- not more than 50! as per PostMetricsData API docs BEGIN -- get the meta-data for this ADB Instance like its OCI compartmentId, region and DBName etc; as JSON in oci_metadata_json_result SELECT CLOUD_IDENTITY INTO OCI_METADATA_JSON_RESULT FROM V$PDBS; -- dbms_output.put_line(oci_metadata_json_result); -- convert the JSON string into PLSQL JSON native JSON datatype json_object_t variable named oci_metadata_json_result OCI_METADATA_JSON_OBJ := JSON_OBJECT_T.PARSE(OCI_METADATA_JSON_RESULT); WHILE(TRUE) LOOP SELECT COUNT(*) INTO TOTAL_METRICS_STREAM_CNT FROM SHOPPING_ORDER_METRICS_TABLE; IF(TOTAL_METRICS_STREAM_CNT < BATCH_SIZE_FOR_EACH_POST) THEN DBMS_OUTPUT.PUT_LINE('Only ' || TOTAL_METRICS_STREAM_CNT || ' metrics datapoints buffered(less than batch size' || BATCH_SIZE_FOR_EACH_POST || '), hence waiting for buffer to fill up'); EXIT; END IF; OCI_POST_METRICS_BODY_JSON_OBJ := PREPARE_JSON_OBJECT_FROM_METRIC_ROWS(OCI_METADATA_JSON_OBJ, BATCH_SIZE_FOR_EACH_POST); ADB_REGION := OCI_METADATA_JSON_OBJ.GET_STRING('REGION'); HTTP_CODE := POST_METRICS_DATA_TO_OCI(OCI_POST_METRICS_BODY_JSON_OBJ, ADB_REGION); IF(HTTP_CODE = 200) THEN DBMS_OUTPUT.PUT_LINE('Deleting the published metrics'); DELETE FROM SHOPPING_ORDER_METRICS_TABLE WHERE ID IN (SELECT ID FROM SHOPPING_ORDER_METRICS_TABLE ORDER BY CREATED_DATE DESC FETCH FIRST 50 ROWS ONLY); END IF; COMMIT; -- PostMetricData API has TPS rate limit of 50, just for safety -- Hence sleep for atleast seconds => (1/50) to avoid throttling -- DBMS_SESSION.SLEEP(seconds => (1/50)); END LOOP; END; /
A função
POST_METRICS_DATA_TO_OCI
chama a API PostMetricsData. Como acontece com cada API do Oracle Cloud, você precisa de autorização adequada do OCI IAM para chamá-la. Você passa o mesmo que a seguir, com o parâmetro nomeadocredential_name => 'OCI$RESOURCE_PRINCIPAL'
.A credencial de banco de dados
OCI$RESOURCE_PRINCIPAL
está vinculada ao grupo dinâmicoadb_dg
que você criou na etapa 2 e o usuárioECOMMERCE_USER
da etapa 3 já tem acesso.Assim, por cadeia de confiança, este script PL/SQL executado por
ECOMMERCE_USER
tem autorização para postar as métricas personalizadas no serviço de Monitoramento do OCI.RESP := DBMS_CLOUD.SEND_REQUEST(CREDENTIAL_NAME => 'OCI$RESOURCE_PRINCIPAL', URI => 'https://telemetry-ingestion.'|| ADB_REGION|| '.oraclecloud.com/20180401/metrics', METHOD =>DBMS_CLOUD.METHOD_POST, BODY => UTL_RAW.CAST_TO_RAW(OCI_POST_METRICS_BODY_JSON_OBJ.TO_STRING));
dbms_cloud.send_request
é um procedimento armazenado PL/SQL incorporado que chama qualquer ponto final rest, pré-instalado com cada Oracle Autonomous Database. Aqui a usamos para chamar a API REST do serviço de Monitoramento do OCI.O procedimento armazenado
PUBLISH_BUFFERED_METRICS_TO_OCI
publica todas as métricas armazenadas no buffer para o serviço OCI Monitoring usando todas as funções e procedimentos discutidos até o momento. Para ser executado, ele cria lotes do tamanhoBATCH_SIZE_FOR_EACH_POST
de pontos de dados de métrica para cada chamada de API PostMetricsData.
-
-
Programe e execute scripts das etapas 4 e 5. Nas etapas 4 e 5, você definiu procedimentos e funções armazenados no Oracle Database, mas ainda não os executou.
-
Execute o script na etapa 4 para preencher os dados na tabela
SHOPPING_ORDER
. O script será executado por aproximadamente 15 minutos na instância do Oracle Autonomouse Transaction Processing com 1 OCPU e 1 TB de armazenamento.-- we schedule the data feed to run immediately, asynchronously and only once! BEGIN DBMS_SCHEDULER.CREATE_JOB( JOB_NAME => 'POPULATE_DATA_FEED_JOB', JOB_TYPE => 'STORED_PROCEDURE', JOB_ACTION => 'POPULATE_DATA_FEED', ENABLED => TRUE, AUTO_DROP => TRUE, -- drop job after 1 run. COMMENTS => 'ONE-TIME JOB'); END; / -- just for our information SELECT STATUS,count(*) FROM SHOPPING_ORDER GROUP BY STATUS;
-
O único restante é a execução periódica do script PL/SQL na etapa 5: computação e publicação no serviço OCI Monitoring.
Fazemos da seguinte forma com o procedimento armazenado incorporado PL/SQL
DBMS_SCHEDULER.CREATE_JOB
.Ele cria o Oracle Database
SCHEDULED_JOB
com duração de 20 minutos (1.200 segundos). Ele faz computação de métricas personalizadas e as publica a cada minuto.Para um caso de uso de produção, configure-o de acordo com suas necessidades.
BEGIN DBMS_SCHEDULER.CREATE_JOB( JOB_NAME => 'POST_METRICS_TO_OCI_JOB', JOB_TYPE => 'PLSQL_BLOCK', JOB_ACTION => 'BEGIN ECOMMERCE_USER.COMPUTE_AND_BUFFER_METRICS(); ECOMMERCE_USER.PUBLISH_BUFFERED_METRICS_TO_OCI(); END;', START_DATE => SYSTIMESTAMP, -- start the first run immediately REPEAT_INTERVAL => 'FREQ=SECONDLY;INTERVAL=60', -- run this PLSQL_BLOCK every 60th second END_DATE => SYSTIMESTAMP + INTERVAL '1200' SECOND, -- this schedule is only active AUTO_DROP => TRUE, -- delete the schedule after 1200 seconds, effectively after its last run ENABLED => TRUE, -- enable this schedule as soon as it is created COMMENTS => 'JOB TO POST DB METRICS TO OCI MONITORING SERVICE, RUNS EVERY 10TH SECOND'); END; /
-
-
Explore as métricas personalizadas publicadas na Console do Oracle Cloud.
-
No menu de navegação, clique em Explorador de Métricas.
-
No Explorador de Métricas, selecione o namespace como
custom_metrics_from_adb
, resourceGroup comoecommerece_adb
e o nome da métrica comocustomer_orders_submitted
que você definiu para métricas personalizadas.Todos os metadados e dimensões definidos para as métricas personalizadas estão disponíveis.
Você pode construir consultas MQL para analisar essas métricas de acordo com suas necessidades e caso de uso. Em seguida, talvez você queira configurar Alarms do Oracle Cloud no fluxo de métricas para alertar sua equipe operacional.
Isso automatiza o loop de observabilidade das métricas do Oracle Autonomous Database à sua escolha.
-
Conclusão
Você aprendeu a emitir métricas personalizadas do Oracle Autonomous Database para o serviço de Monitoramento do Oracle Cloud Infrastructure (OCI) com scripts PL/SQL simples usando o OCI SDK para PL/SQL. O Oracle Database é uma "fonte de verdade" para muitos dos fluxos de trabalho de negócios, então essa é uma funcionalidade muito poderosa.
Métricas personalizadas são cidadãos de primeira classe do serviço de Monitoramento de OCI, juntamente com métricas nativas. Você pode analisá-los com a mesma Linguagem de Consulta de Métricas avançada e configurar Alarms para notificá-lo sempre que ocorrer qualquer evento de interesse ou problema.
Isso dá a você a última exibição de 'Painel Único de Vidro' para todas as suas métricas, seja ela gerada pelo Serviço OCI ou métricas personalizadas geradas por seus aplicativos e bancos de dados.
Agradecimentos
- Autor - Mayur Raleraskar, Arquiteto de Soluções
Mais Recursos de Aprendizagem
Explore outros laboratórios em docs.oracle.com/learn ou acesse mais conteúdo de aprendizado gratuito no canal YouTube do Oracle Learning. Além disso, visite education.oracle.com/learning-explorer para se tornar um Oracle Learning Explorer.
Para obter a documentação do produto, visite o Oracle Help Center.
Publish custom metrics from Oracle Autonomous Database using Oracle Cloud Infrastructure Monitoring service
F50480-01
November 2021
Copyright © 2021, Oracle and/or its affiliates.