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

garrick

Well-Known Member
Lotus team
26.10.2009
865
68
Москва
#1
Есть база в которой сохраняется история обработки документа. По мере обработки, при переходе со статуса на статус каждый раз создаётся новый response документ в который записывается кто, что и когда сделал. Таким образом на один полезный документ создаётся десятка полтора ответных документов истории. Мне кажется, не очень здорово иметь слишком много документов в базе. Есть идея хранить историю в каком-нибудь RT поле в виде XML или JSON. Показывать можно как HTML табличку в диалоговом окне. Коллеги, похвалите мою идею или поругайте, или посоветуйте чего-нибудь. А то мож... лучше и не трогать пока работает?
 

savl

Well-Known Member
Lotus team
28.10.2011
2 116
157
32
#2
Видел 2 реализации.
1. Класс History
2. Через отдельные документы, но в другой базе, а не в этой же.

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

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

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

lmike

нет, пердело совершенство
Lotus team
27.08.2008
6 433
351
homepage.mac.com
#3
можно РТ, можно аттач (тогда и показывать внешним ср-вом), вопрос будет в создание дока на сессию, чтобы исключить конфликты и потерю
аттач - хорош тем, что файло может создаваться на диске и цепляться после завершения "транзакции", если не цепанулось (упала нотусня) - проверяем диск на файло , при начале новой сессии и цепляем
И в этом случае есть засада - кэширование файловых операций (если нотусня брыкнулась - не все записи попадут в файл)
вариант (кастыль) - время от времени переоткрывать файл

Добавлено: вот наброски <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">
Код:
''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
 

lmike

нет, пердело совершенство
Lotus team
27.08.2008
6 433
351
homepage.mac.com
#4
вызов последнего лога
Код:
	Dim mylog As New LogObj()
Call mylog.GetLastLogDoc()
 

akat

Well-Known Member
Lotus team
16.06.2010
243
7
#5
Есть база в которой сохраняется история обработки документа. По мере обработки, при переходе со статуса на статус каждый раз создаётся новый response документ в который записывается кто, что и когда сделал. Таким образом на один полезный документ создаётся десятка полтора ответных документов истории. Мне кажется, не очень здорово иметь слишком много документов в базе. Есть идея хранить историю в каком-нибудь RT поле в виде XML или JSON. Показывать можно как HTML табличку в диалоговом окне. Коллеги, похвалите мою идею или поругайте, или посоветуйте чего-нибудь. А то мож... лучше и не трогать пока работает?
Использовали такой подход: респонс на каждый шаг по процессу. Удобно светить сейм-тайм статус сотрудников, обработавших документ. По завершению финишного статуса процесса все респонсы удалялись и рисовалась табличка в РТ-поле. Которая еще и могла распечататься при желании.
Подход очень себя оправдал.
 

garrick

Well-Known Member
Lotus team
26.10.2009
865
68
Москва
#6
Использовали такой подход: респонс на каждый шаг по процессу. Удобно светить сейм-тайм статус сотрудников, обработавших документ. По завершению финишного статуса процесса все респонсы удалялись и рисовалась табличка в РТ-поле. Которая еще и могла распечататься при желании.
Подход очень себя оправдал.
У нас есть некоторые процессы, которые не кончаются никогда. Т.е. может возникнут ситуация, когда "а помните у вас два года назад был какой-то документик, по нему сейчас пришел запрос/жалоба и т.п." Надо документик найти и снова запустить в обработку (разбирательство что там с ним было не так...)". Поэтому возникла идея сразу хранить историю в каком-то поле в самом документе, а не в респонзах. Сразу RT- что бы не было проблем с 32К. Остаётся под вопросом вообще целесообразность этого (будет ли в чём нибудь выигрыш?) и формат хранения. Например, XML удобно заполнять и читать, при наложении XSL шаблона можно нарисовать красивую табличку для демонстрации пользователю. Некритичен к смене формата - добавлении нового или удаления поля, т.е в истории могут одновременно хранится строки с записями нового и старого формата и код работающей с этой историей не сломается, просто не будет показывать новые поля про которые он не знает или пробелы вместо удалённых полей. Минусы - слишком много букв (размер поля), нормально с XML можно работать только на Java, для LS нет штатных средств.
 

oshmianski

Достойный программист
Lotus team
25.04.2012
546
13
#7
я использую xml в RT поле самого же документа.
отображение или табличкой в RT поле или java апплет.
 

Darkhan

Well-Known Member
Lotus team
14.12.2012
98
4
32
Astana
#8
А как насчет симбиоза?
1) Создаем БД Логи
2) Заводим отдельный псевдодокумент, связь с оригинальным документом реаизуется через поиск по ключу во вьюхе, либо через DigestSearch
3) Респонзим логи к псевдодокументу
4) При достижении критичного кол-ва респонзов перекидываем (аппендим) в RT поле псевдодокумента (текст, или аттач). Контроль числа респонзов можно перекинуть на еженощный агент.
5) Показывать юзеру последние n логов из числа респонзов с возможностью порыться в архивах логов из псевдодокумента

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

lmike

нет, пердело совершенство
Lotus team
27.08.2008
6 433
351
homepage.mac.com
#9
пополнение текстового RT поля, в котором уже не один килобайт инфы, в реалтайме очень тормозящий процесс
еще одна причина сохранять в файл (кот. можно еще и плющить)
 

erdi

Well-Known Member
20.08.2008
265
36
35
Краснодар
#10
а чем не устраивает другая база, в которой хранятся все эти логи? как ранее замечено поиск по ключу во вьюхе, либо через DigestSearch
документ меняет не только пользователь в UI, но еще и агенты в фоне или на сервере, к тому же если ведется запись только в один документ до "полного заполнения", то надо как-то придумывать механизм моно-доступа, чтобы не создавать конфликты, когда несколько пользователей жмут "ознакомлено" или меняют/дополняют основной документ своими данными
в отдельной базе описать форму события с полями и заполнять...не важно кто изменил - создался новый документ событие
Для красивого UI просмотра логов можно RT поле использовать, которое рисует таблицу в момент открытия(данное поле можно повесить в подформу, чтобы лишний раз когда не надо не вызывалась), можно html таблицу рисовать, можно внешний файл...кому что нужно в данный момент