Как Лучше Хранить Историю По Документу?

Тема в разделе "Lotus - Программирование", создана пользователем garrick, 13 май 2014.

  1. garrick

    garrick Lotus team
    Lotus team

    Регистрация:
    26 окт 2009
    Сообщения:
    770
    Симпатии:
    50
    Есть база в которой сохраняется история обработки документа. По мере обработки, при переходе со статуса на статус каждый раз создаётся новый response документ в который записывается кто, что и когда сделал. Таким образом на один полезный документ создаётся десятка полтора ответных документов истории. Мне кажется, не очень здорово иметь слишком много документов в базе. Есть идея хранить историю в каком-нибудь RT поле в виде XML или JSON. Показывать можно как HTML табличку в диалоговом окне. Коллеги, похвалите мою идею или поругайте, или посоветуйте чего-нибудь. А то мож... лучше и не трогать пока работает?
     
  2. savl

    savl Lotus team
    Lotus team

    Регистрация:
    28 окт 2011
    Сообщения:
    2.051
    Симпатии:
    146
    Видел 2 реализации.
    1. Класс History
    2. Через отдельные документы, но в другой базе, а не в этой же.

    На старой работе использовалась вторая реализация (очень много разных действий требовалось логировать), на текущей сделали первую (не требовалось все подряд, только основное).

    Добавлено: Плюс первой - хранится в самом документе, легкая реализация.
    Минусы: 32К, там текстовое поле используется, а не RT

    Плюс второй: легко заменить одну базу на другую в случае большого количества документов.
    Минусы: достаточно сложная реализация, наличие реплик всех баз "истории" на всех серверах для доступа.
     
  3. lmike

    lmike нет, пердело совершенство
    Команда форума Lotus team

    Регистрация:
    27 авг 2008
    Сообщения:
    6.073
    Симпатии:
    299
    можно РТ, можно аттач (тогда и показывать внешним ср-вом), вопрос будет в создание дока на сессию, чтобы исключить конфликты и потерю
    аттач - хорош тем, что файло может создаваться на диске и цепляться после завершения "транзакции", если не цепанулось (упала нотусня) - проверяем диск на файло , при начале новой сессии и цепляем
    И в этом случае есть засада - кэширование файловых операций (если нотусня брыкнулась - не все записи попадут в файл)
    вариант (кастыль) - время от времени переоткрывать файл

    Добавлено: вот наброски <div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">"обертка"</div></div><div class="sp-body"><div class="sp-content">
    Код (LotusScript):
    ''logging
    Class LogObj As ErrorHandler
    Private logdoc As NotesDocument 'при создании не сохраняется, инициализация - CreateLogDoc
    Private logbody As NotesRichTextItem
    Private logfileStream As NotesStream
    Private tmpfileName As String
    Private CodePage As String
    Private toRTFlag As Boolean

    Sub New()
    CodePage="UTF-8"
    toRTFlag=False
    Call CreateLogDoc()
    End Sub
    Property Set toRT(b As Boolean)
    toRTFlag=b
    End Property
    Sub Delete()
    Call Closelog()
    End Sub
    Function CreateLogDoc() As NotesDocument
    On Error Goto ErrorHandler
    Dim ses As New NotesSession
    Dim db As NotesDatabase

    Set db=ses.CurrentDatabase
    Set logdoc=db.CreateDocument()
    Call logdoc.ReplaceItemValue({Form},{processLog})  
    Set logbody=logdoc.CreateRichTextItem({body})
    tmpfileName=GetNotesTempDirectory()&{\}& logdoc.UniversalID &{.txt}
    Set CreateLogDoc=logdoc
    ExitFunction:
    Exit Function
    ErrorHandler:
    Call Me.RaiseError()
    Resume ExitFunction
    End Function
    '***************************************
    Function OpenLogDocWks(wks As NotesUIWorkspace) As NotesUIDocument
    On Error Goto ErrorHandler
    If Not logdoc Is Nothing Then
    Call Me.CloseLog()
    If wks Is Nothing Then
    Dim logwks As New NotesUIWorkspace 
    Set OpenLogDocWks=logwks.EditDocument(False,logdoc,True)
    Else
    Set OpenLogDocWks=wks.EditDocument(False,logdoc,True)
    End If
    End If
    ExitFunction:
    Exit Function
    ErrorHandler:
    Call Me.RaiseError()
    Resume ExitFunction
    End Function
    '***************************************
    Function OpenLogDoc() As NotesUIDocument
    Set OpenLogDoc=OpenLogDocWks(Nothing)
    End Function
    '***************************************
    Function GetLastLogDoc() As NotesUIDocument
    Dim db As NotesDatabase
    Dim wks As New NotesUIWorkspace
    Dim ses As New NotesSession
    On Error Goto ErrorHandler 

    Set db=ses.CurrentDatabase

    Dim coll As NotesDocumentCollection
    Set coll=db.AllDocuments

    Dim doc As NotesDocument
    Set doc=coll.GetLastDocument
    Do While Not doc Is Nothing
    If doc.Form(0)="processLog" Then
    Exit Do
    End If
    Loop
    If doc Is Nothing Then Exit Function
    Set logdoc=doc
    Set GetLastLogDoc=OpenLogDoc()
    ExitFunction:
    Exit Function
    ErrorHandler:
    Call Me.RaiseError()
    Resume ExitFunction
    End Function
    '***************************************
    Function WriteLogDoc(txt As String) As Boolean
    On Error Goto ErrorHandler
    If toRTFlag Then
    If Not logbody Is Nothing Then
    logbody.AppendText(txt)
    logbody.AddNewline(1)
    End If
    Else
    Call WriteLogDocFile(txt)
    End If
    WriteLogDoc=True
    ExitFunction:
    Exit Function
    ErrorHandler:
    Call Me.RaiseError()
    Resume ExitFunction
    End Function
    '***************************************
    Function WriteLogDocFile(txt As String) As NotesStream
    On Error Goto ErrorHandler
    If logfileStream Is Nothing Then
    Dim ses As New NotesSession
    Set logfileStream=ses.CreateStream()
    Call logfileStream.Open(tmpfileName, CodePage)
    Call logfileStream.WriteText(txt,EOL_CRLF)
    Else
    Call logfileStream.WriteText(txt,EOL_CRLF)
    End If
    ExitFunction:
    Exit Function
    ErrorHandler:
    Call Me.RaiseError()
    Resume ExitFunction
    End Function
    '***************************************
    Function CloseLog() As Boolean
    On Error Goto ErrorHandler
    If CloseLog Then Goto ExitFunction
    If (Not logfileStream Is Nothing) Then
    Call logfileStream.Close()
    If (Not logdoc Is Nothing) Then
    Call AddAttachment(tmpfileName,logdoc, {body})
    Kill tmpfileName
    End If
    End If
    If (Not logdoc Is Nothing) Then Call logdoc.Save(True,False)
    CloseLog=True
    ExitFunction:
    Exit Function
    ErrorHandler:
    Call Me.RaiseError()
    Resume ExitFunction
    End Function
    End Class
     
  4. lmike

    lmike нет, пердело совершенство
    Команда форума Lotus team

    Регистрация:
    27 авг 2008
    Сообщения:
    6.073
    Симпатии:
    299
    вызов последнего лога
    Код (LotusScript):
        Dim mylog As New LogObj()
    Call mylog.GetLastLogDoc()
     
  5. akat

    akat Lotus team
    Lotus team

    Регистрация:
    16 июн 2010
    Сообщения:
    243
    Симпатии:
    7
    Использовали такой подход: респонс на каждый шаг по процессу. Удобно светить сейм-тайм статус сотрудников, обработавших документ. По завершению финишного статуса процесса все респонсы удалялись и рисовалась табличка в РТ-поле. Которая еще и могла распечататься при желании.
    Подход очень себя оправдал.
     
  6. garrick

    garrick Lotus team
    Lotus team

    Регистрация:
    26 окт 2009
    Сообщения:
    770
    Симпатии:
    50
    У нас есть некоторые процессы, которые не кончаются никогда. Т.е. может возникнут ситуация, когда "а помните у вас два года назад был какой-то документик, по нему сейчас пришел запрос/жалоба и т.п." Надо документик найти и снова запустить в обработку (разбирательство что там с ним было не так...)". Поэтому возникла идея сразу хранить историю в каком-то поле в самом документе, а не в респонзах. Сразу RT- что бы не было проблем с 32К. Остаётся под вопросом вообще целесообразность этого (будет ли в чём нибудь выигрыш?) и формат хранения. Например, XML удобно заполнять и читать, при наложении XSL шаблона можно нарисовать красивую табличку для демонстрации пользователю. Некритичен к смене формата - добавлении нового или удаления поля, т.е в истории могут одновременно хранится строки с записями нового и старого формата и код работающей с этой историей не сломается, просто не будет показывать новые поля про которые он не знает или пробелы вместо удалённых полей. Минусы - слишком много букв (размер поля), нормально с XML можно работать только на Java, для LS нет штатных средств.
     
  7. oshmianski

    oshmianski Достойный программист
    Lotus team

    Регистрация:
    25 апр 2012
    Сообщения:
    512
    Симпатии:
    13
    я использую xml в RT поле самого же документа.
    отображение или табличкой в RT поле или java апплет.
     
  8. Darkhan

    Darkhan Well-Known Member

    Регистрация:
    14 дек 2012
    Сообщения:
    95
    Симпатии:
    4
    А как насчет симбиоза?
    1) Создаем БД Логи
    2) Заводим отдельный псевдодокумент, связь с оригинальным документом реаизуется через поиск по ключу во вьюхе, либо через DigestSearch
    3) Респонзим логи к псевдодокументу
    4) При достижении критичного кол-ва респонзов перекидываем (аппендим) в RT поле псевдодокумента (текст, или аттач). Контроль числа респонзов можно перекинуть на еженощный агент.
    5) Показывать юзеру последние n логов из числа респонзов с возможностью порыться в архивах логов из псевдодокумента

    Из личного опыта: пополнение текстового RT поля, в котором уже не один килобайт инфы, в реалтайме очень тормозящий процесс
     
  9. lmike

    lmike нет, пердело совершенство
    Команда форума Lotus team

    Регистрация:
    27 авг 2008
    Сообщения:
    6.073
    Симпатии:
    299
    еще одна причина сохранять в файл (кот. можно еще и плющить)
     
  10. erdi

    erdi Well-Known Member

    Регистрация:
    20 авг 2008
    Сообщения:
    261
    Симпатии:
    36
    а чем не устраивает другая база, в которой хранятся все эти логи? как ранее замечено поиск по ключу во вьюхе, либо через DigestSearch
    документ меняет не только пользователь в UI, но еще и агенты в фоне или на сервере, к тому же если ведется запись только в один документ до "полного заполнения", то надо как-то придумывать механизм моно-доступа, чтобы не создавать конфликты, когда несколько пользователей жмут "ознакомлено" или меняют/дополняют основной документ своими данными
    в отдельной базе описать форму события с полями и заполнять...не важно кто изменил - создался новый документ событие
    Для красивого UI просмотра логов можно RT поле использовать, которое рисует таблицу в момент открытия(данное поле можно повесить в подформу, чтобы лишний раз когда не надо не вызывалась), можно html таблицу рисовать, можно внешний файл...кому что нужно в данный момент
     
Загрузка...

Поделиться этой страницей