2016-09-05 2 views
1

정기적으로 원격 데이터베이스를 폴링하고 로그 파일에 다음 요소를 기록하는 간단한 bash 스크립트를 작성하려고합니다. 이 스크립트의 목적은 적극적으로 모니터링하고 응답 시간을 기록sqlplus로 폴링하고 파일에 결과를 로깅하면 라인 쉬프트가 발생합니다.

Mon Sep 5 13:28:30 CEST 2016,1473074940127,text content, 4 
Mon Sep 5 13:28:40 CEST 2016,1473074940127,text content, 3 
Mon Sep 5 13:28:50 CEST 2016,1473074940127,text content, 2 

입니다 :

Readable timestamp, timestamp, string, Request Duration 

예 결과가 모양은 다음과 같습니다 마지막 두 요소는 SQL 쿼리에서 행 요소는 우리의 로컬 환경에서 원격 데이터베이스로, 그래서 우리는 테스트를하는 동안 로컬 응용 프로그램의 오류, 최종 데이터베이스 연결 문제 또는 이와 유사한 오류. 이런 이유로 우리는 스크립트가 어떤 최종 오류 메시지도 출력하기를 원합니다. 이것들의 포맷팅은 중요하지 않지만 우리는 표준 출력이 "편한"원 - 라이너라고보고 싶습니다.

나는 경우를위한 다음과 같은 매우 간단한 스크립트를 작성했습니다

,하지만 내가 상관없이 제거 할 수없는 것 몇 기행을 가지고 어떻게 그것을 조정 :

sleep_duration=10 
while true; do 

SECONDS=0 
timestamp="$(date)," 
echo -n $timestamp >> $LOG_PATH 


sqlplus -s $database <<EOF>> $LOG_PATH 
    whenever sqlerror exit sql.sqlcode 

    set echo off 
    set heading off 
    set linesize 1000 
    set pagesize 0 
    set numformat 9999999999999 
    set colsep , 
    set null null 

    SELECT COLUMN1, COLUMN2 FROM TABLE1; 
    exit; 
EOF 

echo ', '$SECONDS >> $LOG_PATH 

sleep $sleep_duration 
done 

우리가에 보내는 쿼리를 데이터베이스는 항상 두 개의 요소가있는 한 행을 반환하며 두 요소 (INTEGER, VARCHAR2)는 항상 고정 된 너비입니다. 우리 애플리케이션에서 무언가가 국부적으로 깨지면 둘 다 null이 될 수 있습니다.

SPOOL 및 TIMING 명령이 있음을 알고 있지만 두 가지 모두를 테스트하고 사용하지 않도록 선택했습니다. 쿼리를 스풀링하면 적어도 오류 터미널 출력을 사용하지 않고도 로그 파일에 갑작스러운 오류를 출력하지 않으므로 처음에는 파이프 솔루션을 사용했습니다. 단순 해 보였습니다. TIMING은 데이터베이스 가동 중지 시간의 경우 쿼리 경과 시간을 올바르게 표시하지 못했기 때문에 SECONDS 방식을 사용했습니다. 포함 된 모든 sqlplus 오버 헤드와 관련하여 이것이 정확하지는 않지만 정확한 메트릭에 관심이 없다는 것을 알기 때문에 일반적으로 프로세스가 1 초 미만으로 진행되는지 또는 몇 분 이내에 완료되는지 여부를 확인하는 데 관심이 있습니다. 밀리 초는 본질적으로 관련이 없습니다.

이 로그는 다음과 같이 찾고 끝으로, 그러나 하나의 큰 문제가있다 :

Mon Sep 5 14:50:47 CEST 2016, 1473079873483,text output 

, 0 
Mon Sep 5 14:50:57 CEST 2016, 1473079883483,text output 

, 0 
Mon Sep 5 14:51:07 CEST 2016, 1473079893489,text output 

, 0 

내가 결과에서 이러한 모든 후행 lineshifts를 제거 set pagesize 0을 기대하지만 후 2 lineshifts있을 것 같습니다 각 쿼리에 관계없이, 그리고 내가 뭘하려고해도 상관 없어요. 쿼리를 스풀링하면 동일한 결과가 나타납니다.

대신 sqlplus-session 내부에서 루핑을 고려했지만 스크립트는 다소 영구적으로 실행되어야하므로 바람직하지 않은 기능적으로 의미없는 목적을 위해 연결 슬롯을 영구적으로 예약 할까 우려됩니다. . 필요할 때 열거 나 닫는 것이 더 합리적인 것 같습니다. 나는 이런 이유로 주로이 접근법을 테스트하지 않았습니다.

어떤 종류의 오류 항목이 거기에 나타날지 모르기 때문에 로그의 사후 처리를 피하기 위해 나중에 불필요한 regex-nightmare와 같은 느낌이 들게됩니다.

최종 출력을 불필요한 줄 바꾸기 및 공백없이 한 줄에 정리하는 방법에 대한 제안 사항이 있습니까?

+0

문자열 열의 데이터 형식은 무엇입니까? varchar2라고했지만 실제로 char 또는 clob이 아닙니다. 얼마나 큰가? 문자열 값에는 공백이나 포함 된 줄 바꿈 문자가 있습니까? –

+0

문자열 값은 일반 URL이고 필드는 varchar2 (250)로 선언되며 실제 내용 길이는 null 또는 약 60 자입니다. 공백이나 개행 문자, 삽입 된 행간, 선행 행 또는 후행 행은 없습니다. 비록 3 중 점검을 할지라도 검증 할 줄 바꿈이 없습니다. 존재하지 않아야하지만 URL이 부분적으로 생성되므로 확인하지 않고 100 % 확실하지 않습니다. –

+0

텍스트 필드에 공백이나 개행 문자가 전혀없는 것을 확인할 수 있으며 문자열의 길이는 항상 정확히 36 자입니다. –

답변

1

이것은 아직 설명 할 수 없었던 라인 변주를 실제로 해결하지 않았으므로 해결 방법이 있지만 간단한 해결책은 간단히 sqlplus 출력을 직접 저장하는 것입니다. sqlplus에서 직접 로그에 인쇄하려고 시도하는 대신 bash 변수를 사용하고 다른 변수로 표시합니다. 내 자신에이 솔루션을 통해

while true; do 

SECONDS=0 
timestamp=$(date) 
echo -n "$timestamp, " >> $LOG_PATH 

QUERY_RESULT=$(sqlplus -s $database << EOF 
    whenever sqlerror exit sql.sqlcode 

    set echo off 
    set heading off 
    set linesize 1000 
    set pagesize 0 
    set numformat 9999999999999 
    set colsep ', ' 
    set null null 

    SELECT TIME, BROKER_NAME FROM ACTIVEMQ_LOCK; 
    exit; 
EOF 
) 

echo $QUERY_RESULT, $SECONDS seconds elapsed >> $LOG_PATH 

sleep $sleep_duration 
done 

을 비틀 :

기본적으로, 나는 위의 스크립트에서 변경 한 모든 변수 QUERY_OUTPUT = $ (의 SQLPLUS 명령을 바꿈) 출력의 배관을 제거했다 위의 질문에서 시도한 것과 시도하지 않은 것을 문서화하고 검증하려고 시도한 몇 시간을 보내고 몇 가지 테스트를 마친 후 잘 작동하는 것처럼 보입니다. 모든 것이 깔끔하게 제어 가능한 방식으로 한 줄에 인쇄되며, 모든 오류는 그 한 줄에도 깨끗하게 인쇄됩니다. 내가 찾고있는 것을 정확히 볼 수 있습니다.

해결책을 찾은 이후 처음부터 질문을하지 않는 것으로 간주되었지만 누군가 다른 사람도이 값을 볼 수 있다고 생각했습니다. 적어도 눈부신 명백한 중복을 찾을 수 없었습니다. 함께 공유 할 수도 있습니다!

+1

테스트 할 시스템이 없지만 한 줄로 압축 할 수있는 것처럼 보입니다. 즉,'echo $ QUERY_RESULT ", $ SECONDS 초가 경과 한">> $ LOG_PATH'입니다. SQL 처리에서 여분의 새로운 행을 없애는 방법이있을 수 있지만 이것은 목적에 충분할 것입니다 (그러나'$ SECONDS '가있는 이유는 모르겠지만 리터럴 값'$ SECONDS'을 생성 할 것입니다.).) 행운을 빕니다. – shellter

+0

아 물론. 그것은 필자가 생각하기에 두 개의 "문제"가 있다고 생각하기 때문에 두 줄로 끝난다. 그것으로 편집 할 것입니다! –

+0

ticked-in SECONDS 비트는 틱이 초를 래핑하지 않고 앞뒤 텍스트를 래핑합니다. 나는 원래 배쉬에 정통한 노련한 베테랑이 아니기 때문에, 그들이 필요 없다는 것을 알지조차 못했다. 신속하게 테스트하고 둘 다 수정하여 수정합니다. 누군가가 즉각적인 속임수를 보았지만, 줄 바꿈 줄을 없애 버렸 더라면 좋겠지 만, 내 해결 방법은이 특별한 상황에 완벽하게 맞습니다.하지만 반드시 그런 것은 아닙니다. –