반응형


작업을 처리하고 그 기록을 남기는 방법들은 어느 플랫폼, 어느 데이터베이스, 어느 os든간에 관리자라면 필요한 기능일 것이다. 물론 이러한 Log를 데이터베이스에 바로 쌓아도 되겠지만..

큰 프로시져에서 sub procedure를 호출하는 경우라고 가정해보자. Sub procedure에서 실행하며 그 작업들을 데이터베이스에 바로 쌓으려고 하고 있는데 이 sub procedure를 호출한 큰 프로시져에서 transaction 처리로 rollback을 하고 있다면.. 프로시져의 에러를 어떻게 Tracking 해야 할까?

어떤 곳에서는 파일로 처리하는 경우가 있으며, 이 데이터를 데이터베이스에 올려서 처리하기도 할 것이다.

 

그런데 이번에 하고자 하는 것은 이런 과정이 아니라 윈도우 이벤트에 로그를 남기는 작업을 해볼까 한다.

 

먼저 mssql에서 이미 제공하고 있는 procedure, 함수를 이용해서 로그를 남기려면 아래를 사용하면 된다.


 

DECLARE @desc VARCHAR(100)

SET @desc = 'sp...'

RAISERROR (@desc  ,0, 0) with LOG

 

EXEC xp_logevent 50001, @desc, informational

 

***참고 powershell 새항목 30 항목에 대해 export하기

Get-eventLog -logname "application" -newest 30 | where-object {$_.Source -like "*MSSQLSERVER*"} | Export-csv c:\DBScript\sqlevent.csv



위의 명령으로 실행하면 응용 프로그램이라는 카테고리에 Log가 쌓이게 된다.

 

그런데 이 로그를 다시 읽으려면 어떻게 해야 하는가? 또는 event log를 지우려면 어떻게 해야 할까? 새로운 이벤트 카테고리(나만의)를 생성해서 다른 것과 섞이지 않게 하려면 어떻게 해야할까? 역시 이런 의문으로 함수를 하나 만들어 작업을 했다.


그런데 이 로그를 다시 읽으려면 어떻게 해야 하는가? 또는 event log를 지우려면 어떻게 해야 할까? 새로운 이벤트 카테고리(나만의)를 생성해서 다른 것과 섞이지 않게 하려면 어떻게 해야할까? 역시 이런 의문으로 함수를 하나 만들어 작업을 했다.

 

솔루션을 하나 만들고 디비를 연결한 다음 아래와 같은 코드를 저장하십시오..

아래의 솔루션에는 event view관련 네 개의 함수로 구성되어 있습니다.

Write , Read, Backup, Clear이 넷으로 구성했다. 그리고 Read를 제외한 함수들은 작업의 성공여부 1, 0으로 리턴한다. Read는 지금 탭으로 구분한 데이터에 대해 테이블로 리턴하게 했다.


using System;

using System.Data;

using System.Data.SqlClient;

using System.Data.SqlTypes;

using Microsoft.SqlServer.Server;

using System.Diagnostics;

using System.IO;

using System.Collections;

 

 

public partial class UserDefinedFunctions

{

  

    [Microsoft.SqlServer.Server.SqlFunction(FillRowMethodName = "FillLog", TableDefinition = "Num nvarchar(20), T1 nVarchar(1000), T2 nVarchar(1000)")]

 

    public static IEnumerable udf_read_log(string cs)

    {

        string[] sItems;

        string sData = "";

        EventLog eLog = new EventLog(cs);

 

        foreach (EventLogEntry entry in eLog.Entries)

        {

             sData += entry.Message + "#";

        }

 

        try

        {

            sItems = sData.Split('#');

            return (sItems);

        }

        catch

        {

            return null;

        }

 

       

    }

 

    private static void FillLog(Object obj, out SqlString Num, out SqlString T1, out SqlString T2)

    {

        string sTemp = Convert.ToString(obj);

        string[] arr_temp = sTemp.Split('\t');

        try

        {

            Num = (SqlString)arr_temp[0];

            T1 = (SqlString)arr_temp[1];

            T2 = (SqlString)arr_temp[2];

        }

        catch

        {

            Num = null;

            T1 = null;

            T2 = null;

        }

    }

 

 

    [Microsoft.SqlServer.Server.SqlFunction]

    public static SqlInt16 udf_write_log(string message, string cs)

    {

        try

        {

            if (!EventLog.Exists(cs))

            {

                EventLog.CreateEventSource("MSSQL_Trace", cs);

            }

 

            EventLog.WriteEntry(cs, message);

            return 1;

 

        }

        catch (Exception e)

        {

            return 0;

 

        }

 

    }

 

 

    [Microsoft.SqlServer.Server.SqlFunction]

    public static SqlInt16 udf_clear_log(string cs)

    {

        try

        {

            EventLog elog = new EventLog(cs);

            elog.Clear();

            return 1;

        }

        catch

        {

            return 0;

        }

 

    }

 

 

    [Microsoft.SqlServer.Server.SqlFunction]

    public static SqlInt16 udf_backup_log(string pString, string cs)

    {

        try

        {

            EventLog eLog = new EventLog(cs);

            StreamWriter sw = new StreamWriter(pString, true);

            foreach (EventLogEntry entry in eLog.Entries)

            {

                sw.WriteLine(entry.Message);

            }

            sw.Close();

            return 1;

        }

        catch

        {

            return 0;

        }

 

    }

};





컴파일하고 소스를 배포하면 해당 디비에서 아래와 같은 코드를 실행하면 된다.

-write

select common.dbo.udf_write_log('123 234  procedurename_', 'mssql_trace');

--success 1 ,  error 0

 

--backup

select common.dbo.udf_backup_log('d:\mssql_trace.bak', 'mssql_trace');

 

--clear_log

select common.dbo.udf_clear_log('mssql_trace');

 

--read

select * from common.dbo.udf_read_log('mssql_trace')




실행하고 난 다음의 windows log모습이다. query의 결과보다 이게 더 궁금할 듯하여 캡쳐 ^^



첨부 : udf_read_log.cs

반응형

'연구개발 > CLR' 카테고리의 다른 글

CLR - 병렬로 쿼리를 처리하기  (0) 2011.08.27
CLR - 누적합 구하기  (0) 2011.08.27
CLR-이전행가기 udf_lag  (0) 2011.08.27
WMI 객체를 쿼리로 읽어오기  (0) 2010.08.10
파일리스트 불러오기  (0) 2009.06.22

+ Recent posts