로그파일 저장 그리고 로그를 표시하기 위한 코딩.... 프로그램 개발 할 때마다 만들어야 되는 실정... 질려 죽겠어서 클래스로 만들었습니다.

기본 설정

  • 글로벌이나 지역변수로 클래스 변수를 선언합니다.
VB
dim logMgr as claLogMgr
  • 이어서 기본 세팅 들어갑니다.
VB
logMgr.m_LogPath = app.path & "\Log" '로그 경로 설정 logMgr.m_SetAppTitle = app.ProductName '미리 프로젝트 설정에서 ProductName을 설정하시거나 붙박이로 넣어주세요. logMgr.m_SetLogLev = INCLUDE_DEBUG '로그파일 저장 시 어떤 레벨까지 저장할지 지정합니다. 상수는 다음 과 같습니다. ' ESSENTIAL_MESSAGE = 저장하지 않음 ' ONLY_CRITICAL_ERROR = CRITICAL 오류만 저장 ' INCLUDE_MAJOR_ERROR = CRI를 포함한 MAJOR 오류 저장 ' INCLUDE_MINOR_ERROR = CRI, MAJ를 포함한 MINOR 오류 저장 ' INCLUDE_WARNING = CRI, MAJ, MIN을 포함한 WARNING 메시지 저장 ' INCLUDE_COMMON_MESSAGE = 위에 꺼 다 포함 일반 메시지 저장 ' INCLUDE_DEBUG = 위에 꺼 다 포함 DEBUG 메시지까지 저장
  • 위의 상수는 어느레벨을 저장할지에 대한 상수이니 로그에 대한 레벨을 설정할 수 있는 상수도 있어야겠죠.
  • 에러 등급은 개발자 본인이 정하면 됩니다. 로그는 개발자를 위한 것이니까요.
VB
' COMMON_MSG = 일반 메시지 입니다. ' MIN_ERROR = 마이너한 에러. 운영상에 하나도 문제도 없으나, 사용자 실수에 의한 메시지 ' MAJ_ERROR = 운영상에 문제가 없지만 RISK적인 메시지 ' CRI_ERROR = 운영상에 문제가 무진장 많으니 데몬이면 바로 정지 할 수 밖에 없는 상태 ' DEBUG_LOG = 개발자를 위한 디버깅 메시지
  • 이어서 기본설정 다시 들어갑니다.
VB
'위에 SetLev은 파일저장.. 이것은 리스트 박스에의 레벨을 지정합니다. 꼭 파일로는 저장은 해야 하는데 사용자에게 표시할 필요는 없을 때 사용되죠. logmgr.m_SetDisplayLev = INCLUDE_DEBUG
  • 다음은 리스트 박스 세팅입니다. 폼 로딩 시 Set해야겠죠.
VB
Set logMgr.m_ListBox = lstLog 'lstLog라는 리스트박스가 폼에 생성되어 있어야 합니다. Set logMgr.m_chkSchroll = chkSchroll 'chkSchroll이라는 체크박스가 있어야겠죠. 이것은 리스트박스의 스크롤이 가장 밑으로 새로고침되는데 체크를 해제하게 되면 스크롤을 맘대로 가지고 놀 수 있습니다. Set logMgr.m_chkRealTime = chkRealTime 'chkRealTime이라는 체크박스가 있어야 합니다. 체크해제하게 되면 리스트박스에 로그가 추가되지 않습니다. 파일에만 저장이 되죠. 로그 표시때문에 프로그램 운영이 0.00000000000001초라도 느려지게 되면 좀 아니어서 추가하였습니다.

기본적인 사용방법

  • 설정은 다 했다고 생각하고 들어가겠습니다.
VB
logMgr.addLog "프로그램이 시작되었습니다.",
  • 이렇게만 해서 쓰게 되면 기본적인 Optional설정이 되어 사용할 수 있습니다. 완존 기본적인 일반 메시지 추가 시 이렇게 씁니다.
VB
logMgr.addLog "사용자가 맘에 들지 않아요", false, DEBUG_LOG, "그냥", "ProcDebug()", false
  • 이게 풀로 파라미터를 쓴 경우입니다. 다음은 파라미터 설명 드릴께요.
    • [1] str = 로그 메시지죠. 가장 중요하죠.. 꼭 넣어야 합니다.
    • [2] bLstAdd = 리스트박스에 넣을 건지에 대한 여부입니다. 만약 리스트박스 세팅을 하지 않았다면 SKIP합니다.
    • [3] ErrLev = 로그에 대한 에러등급입니다. 기본적으로 COMMON_MSG로 되어 있습니다.
    • [4] ErrCD = 에러코드를 따로 지정할 수 있습니다. 이것은 에러를 사전에 분류가 되어야 합니다. 가령 네트워크, 디비, 사용자오류 이런식으로 분류를 하여 코드를 따서 관리를 하게 되면 로그관리가 비교적 쉬워집니다.
    • [5] sPos = 자바나 웹처럼 몇 번째 줄에서 오류 났는지는 모르지만 인위적으로 어떤 함수에서 에러가 났는지 표현하기 위해서 추가하였습니다.
    • [6] bTimeStr = 로그표시 할때 시간정보를 넣게 되는데 이걸 False로 하게 되면 아무것도 넣지 않고 표시 또는 파일저장합니다.

전체 클래스 소스

아래는 claLogMgr.cls 파일 전문 입니다.
VB
VERSION 1.0 CLASS BEGIN MultiUse = 0 'False Persistable = 0 'NotPersistable DataBindingBehavior = 0 'vbNone DataSourceBehavior = 0 'vbNone MTSTransactionMode = 0 'NotAnMTSObject END Attribute VB_Name = "claLogMgr" Attribute VB_GlobalNameSpace = False Attribute VB_Creatable = True Attribute VB_PredeclaredId = False Attribute VB_Exposed = False Option Explicit ' 로그 등급 Public Enum DISPLAY_ERROR_GRADE COMMON_MSG = 0 MIN_ERROR = 1 MAJ_ERROR = 2 CRI_ERROR = 3 DEBUG_LOG = 4 End Enum ' 파일저장/표시 레벨 Public Enum LOG_GRADE ESSENTIAL_MESSAGE = 0 ONLY_CRITICAL_ERROR = 1 INCLUDE_MAJOR_ERROR = 2 INCLUDE_WARNING = 3 INCLUDE_COMMON_MESSAGE = 4 INCLUDE_DEBUG = 5 End Enum Public m_SetLogLev As LOG_GRADE Public m_SetDisplayLev As LOG_GRADE Public m_SetAppTitle As String Public m_ListBox As ListBox Public m_ChkSchroll As LunaCheck Public m_chkRealtime As LunaCheck Public m_LogPath As String Public Sub ErrLog(errNum As String, errDesc As String, errPos As String) Dim sMsg As String Dim sDispMsg As String Dim sVer As String sVer = App.Major & "." & App.Minor & ".0." & App.Revision sDispMsg = "" sDispMsg = sDispMsg & " [" & Format(Now, "yyyy-mm-dd HH:mm:ss") & " {CRI}] :: " sDispMsg = sDispMsg & "(RUNTIME " & errNum & ") " & errDesc & " {" & errPos & "}" & vbCrLf sDispMsg = sDispMsg & "" & vbCrLf sMsg = sVer & sDispMsg If m_LogPath = "" Then m_LogPath = App.Path & "\Log" End If IsBeingDir m_LogPath FileSave m_LogPath, m_SetAppTitle & "_" & Format(Now, "yyyy-mm-dd") & ".txt", sMsg & vbCrLf If m_ListBox Is Nothing Then Else If m_chkRealtime Is Nothing Then m_ListBox.AddItem sDispMsg Else If m_chkRealtime.Value = True Then m_ListBox.AddItem sDispMsg End If End If If m_ChkSchroll Is Nothing Then m_ListBox.ListIndex = m_ListBox.ListCount - 1 Else If m_ChkSchroll.Value = True Then m_ListBox.ListIndex = m_ListBox.ListCount - 1 End If End If End If End Sub Public Sub AddLog(str As String, Optional bLstAdd As Boolean = True, Optional ErrLev As DISPLAY_ERROR_GRADE = COMMON_MSG, Optional ErrCD As String, Optional sPos As String, Optional bTimeStr As Boolean = True) Dim sMsg As String Dim sDispMsg As String Dim sLev As String Dim sVer As String Select Case ErrLev Case COMMON_MSG sLev = "COM" Case MIN_ERROR sLev = "MIN" Case MAJ_ERROR sLev = "MAJ" Case CRI_ERROR sLev = "CRI" Case DEBUG_LOG sLev = "DBG" End Select sVer = App.Major & "." & App.Minor & ".0." & App.Revision If bTimeStr = True Then sMsg = sVer & " [" & Format(Now, "yyyy-mm-dd HH:mm:ss") & " {" & sLev & "}] :: " & IIf(ErrCD = "", " ", " (" & ErrCD & ") ") & str sDispMsg = "[" & Format(Now, "yyyy-mm-dd HH:mm:ss") & "] :: " & IIf(ErrCD = "", " ", " (" & ErrCD & ") ") & str & " {" & sLev & "}" Else sMsg = str sDispMsg = str End If If m_ListBox Is Nothing Then Else If bLstAdd = True Then If m_SetDisplayLev = COMMON_MSG Then Select Case ErrLev Case DEBUG_LOG, MIN_ERROR, MAJ_ERROR, CRI_ERROR GoTo LogFileSave End Select ElseIf m_SetLogLev = MIN_ERROR Then Select Case ErrLev Case DEBUG_LOG GoTo LogFileSave End Select End If If m_ListBox.ListCount >= 1000 Then m_ListBox.RemoveItem 0 End If If m_chkRealtime Is Nothing Then m_ListBox.AddItem sDispMsg Else If m_chkRealtime.Value = True Then m_ListBox.AddItem sDispMsg End If End If If m_ChkSchroll Is Nothing Then m_ListBox.ListIndex = m_ListBox.ListCount - 1 Else If m_ChkSchroll.Value = False Then m_ListBox.ListIndex = m_ListBox.ListCount - 1 End If End If End If End If LogFileSave: If m_SetLogLev = COMMON_MSG Then Select Case ErrLev Case DEBUG_LOG, MIN_ERROR, MAJ_ERROR, CRI_ERROR Exit Sub End Select ElseIf m_SetLogLev = MIN_ERROR Then Select Case ErrLev Case DEBUG_LOG Exit Sub End Select End If FileSave m_LogPath, m_SetAppTitle & "_" & Format(Now, "yyyy-mm-dd") & ".txt", sMsg & vbCrLf End Sub Private Function FileSave(sFilePath As String, sFileName As String, sMessage As String, Optional bIsBeingDel As Boolean = False) As Boolean '------------------------------------------------------------------------------- ' Function FileSave([파일이름을 제외한 경로], [파일이름], [저장할 문자열], [파일이 있으면 지우는 옵션]) ' 설 명: 하나의 레코드씩 저장하는 함수. ' 리턴값: 성공여부 Y, N '------------------------------------------------------------------------------- On Error GoTo err Dim lOutputFNum As Long, sOutputFileName As String Call IsBeingDir(sFilePath) sFileName = Replace(sFileName, ":", "_") If Right(sFilePath, 1) = "\" Then sOutputFileName = sFilePath & sFileName Else sOutputFileName = sFilePath & "\" & sFileName End If lOutputFNum = FreeFile If bIsBeingDel = False And Dir(sOutputFileName) <> "" Then Open sOutputFileName For Append As #lOutputFNum Else Open sOutputFileName For Output As #lOutputFNum End If Print #lOutputFNum, sMessage; Close lOutputFNum Exit Function err: 'RaiseEvent ErrLog(err.Number, err.Description, "FileSave") err.Clear End Function Private Function IsBeingDir(sDirPath As String, Optional bCreate As Boolean = True) As Boolean '------------------------------------------------------------------------------- ' Function IsBeingDir([폴더경로], [없을경우 생성하고 True반환]) ' 설 명: 폴더가 있는지 체크하고 옵션에 따라 없으면 하위폴더(OS가 지원하는한)까지 생성한다. ' 리턴값: Y/N '------------------------------------------------------------------------------- On Error GoTo err Dim asFolderCount() As String Dim sSplitDir As String Dim iIndex As Integer If Dir(sDirPath, vbDirectory) <> "" Then IsBeingDir = True Exit Function End If asFolderCount = Split(sDirPath, "\") sSplitDir = asFolderCount(0) For iIndex = 1 To UBound(asFolderCount) sSplitDir = sSplitDir & "\" & asFolderCount(iIndex) If Dir(sSplitDir, vbDirectory) = "" Then If bCreate = False Then Exit Function MkDir sSplitDir End If Next IsBeingDir = True Exit Function err: IsBeingDir = False Debug.Print "CODE ERROR! = {IsBeingDir()}" err.Clear End Function