logon logout auditing

  • Hi,

    I need to audit after logon and logout for users.

    i use this article http://www.sqlservercentral.com/articles/SQLServerCentral/sqlserver2005logontriggers/2366/

    but i need to adjust it for this scenario.

    i need to capture the first logon for the user and the last logout for the user and not all logon and logout that the user do while he is in the ERP.

    how can i adjust the script for that or do i need different approach?

    THX

  • you mean the first and last login per day?

    once the data is in the table "Logging " fromt hat article, you can easily create a view that might do a row_number() , or MIN/MAX() /GROUP BY user based on the date to get the first ands lasts on a per day basis.

    so that article puts all teh information in a table, so you can simply query it for the detaisl you need.

    Lowell


    --help us help you! If you post a question, make sure you include a CREATE TABLE... statement and INSERT INTO... statement into that table to give the volunteers here representative data. with your description of the problem, we can provide a tested, verifiable solution to your question! asking the question the right way gets you a tested answer the fastest way possible!

  • hi,

    i need to know how much time the user spent in the erp program.so if the user enter to the program and then he open new windows from that program (this will fire new logon event) and then close the windows (this will fire new logout event) like that all day i'll have a lot of logon and logout events.

    can i use this info to calculate how much real total time the erp program was open on that specific user per day?(we close the erp program if no activity is made for 10 min.)

    THX

  • can you infer that ALL logins are only used for the ERP program?

    a login does not know what database you are connecting to...the login happens before all that.

    assuming you are using the link you provided,I think you'd need to add the application name to the logging table to be sure:

    INSERT INTO Logging (

    EventTime,

    EventType,

    LoginName,

    HostName,

    AppName,

    NTUserName,

    NTDomainName,

    Success,

    FullLog)

    VALUES

    (

    CAST(CAST(@message_body.query('/EVENT_INSTANCE/PostTime/text()') AS VARCHAR(64)) AS DATETIME),

    CAST(@message_body.query('/EVENT_INSTANCE/EventType/text()') AS VARCHAR(100)),

    CAST(@message_body.query('/EVENT_INSTANCE/LoginName/text()') AS VARCHAR(100)),

    CAST(@message_body.query('/EVENT_INSTANCE/HostName/text()') AS VARCHAR(100)),

    CAST(@message_body.query('/EVENT_INSTANCE/ApplicationName/text()') AS VARCHAR(100)),

    CAST(@message_body.query('/EVENT_INSTANCE/NTUserName/text()') AS VARCHAR(100)),

    CAST(@message_body.query('/EVENT_INSTANCE/NTDomainName/text()') AS VARCHAR(100)),

    CAST(CAST(@message_body.query('/EVENT_INSTANCE/Success/text()') AS VARCHAR(64)) AS INTEGER),

    @message_body)

    then you could grab the login/logout pairs, get the datediff in minutes on a per-user basis, and calculate the total time...

    Lowell


    --help us help you! If you post a question, make sure you include a CREATE TABLE... statement and INSERT INTO... statement into that table to give the volunteers here representative data. with your description of the problem, we can provide a tested, verifiable solution to your question! asking the question the right way gets you a tested answer the fastest way possible!

  • after setting up that logging demo example, this query gets me the groups of login/logut elapsed times: note i am testing for a specific application name. i could then add tehm up on a per-day basis...i think that's what you are after.

    /*--results:

    ElapsedMinutes RW LoggingID EventTime EventType LoginName HostName AppName

    7 1 1 2010-07-21 11:49:52.973 AUDIT_LOGIN sa D223 Microsoft SQL Server Management Studio - Query

    NULL 2 7 2010-07-21 11:50:39.067 AUDIT_LOGIN sa D223 Microsoft SQL Server Management Studio - Query

    */

    SELECT

    DATEDIFF(MINUTE,X.EventTime,Y.EventTime) As ElapsedMinutes,

    X.*

    FROM

    (

    select ROW_NUMBER() over (PARTITION BY LoginName,HostName ORDER BY EventTime) AS RW,

    * FROM logging

    WHERE eventtype = 'AUDIT_LOGIN'

    AND AppName = 'Microsoft SQL Server Management Studio - Query'

    ) X

    LEFT OUTER JOIN (

    select ROW_NUMBER() over (PARTITION BY LoginName,HostName ORDER BY EventTime) AS RW,

    * FROM logging

    WHERE eventtype = 'AUDIT_LOGOUT'

    AND AppName = 'Microsoft SQL Server Management Studio - Query')

    Y ON X.LoginName = Y.LoginName

    AND X.HostName = Y.HostName

    AND X.RW = Y.RWc

    Lowell


    --help us help you! If you post a question, make sure you include a CREATE TABLE... statement and INSERT INTO... statement into that table to give the volunteers here representative data. with your description of the problem, we can provide a tested, verifiable solution to your question! asking the question the right way gets you a tested answer the fastest way possible!

  • why i can't filter the login to capture only users that use the erp.

    we have a table with the erp users in database called system.

    when i add the syntax to the proc i get an error message in the sql

    1.The activated proc [dbo].[LoggingProc] running on queue Logging_demo.dbo.LoggingQueue output the following: 'The server principal "sa" is not able to access the database "system" under the current security context.'

    2.The activated proc [dbo].[LoggingProc] running on queue Logging_demo.dbo.LoggingQueue output the following: 'The service queue "LoggingQueue" is currently disabled.'

    from the article with me added syntax in BOLD

    --The proc to handle the events

    -- Set options required for the XML data type.

    SET ANSI_NULLS ON

    GO

    SET QUOTED_IDENTIFIER ON

    GO

    CREATE PROCEDURE LoggingProc

    AS

    SET NOCOUNT ON;

    DECLARE @message_body XML,

    @message_type_name NVARCHAR(256),

    @dialog UNIQUEIDENTIFIER ;

    --Endless loop

    WHILE (1 = 1)

    BEGIN

    BEGIN TRANSACTION ;

    -- Receive the next available message

    WAITFOR (

    RECEIVE TOP(1)

    @message_type_name=message_type_name,

    @message_body=message_body,

    @dialog = conversation_handle

    FROM LoggingQueue

    ), TIMEOUT 2000

    --Rollback and exit if no messages were found

    IF (@@ROWCOUNT = 0)

    BEGIN

    ROLLBACK TRANSACTION ;

    BREAK ;

    END ;

    --End conversation of end dialog message

    IF (@message_type_name = 'http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog')

    BEGIN

    PRINT 'End Dialog received for dialog # ' + cast(@dialog as nvarchar(40)) ;

    END CONVERSATION @dialog ;

    END ;

    ELSE

    BEGIN

    IF (CAST(@message_body.query('/EVENT_INSTANCE/LoginName/text()') AS VARCHAR(100)) in (select USERLOGIN from system.dbo.USERS))

    BEGIN

    INSERT INTO Logging (

    EventTime,

    EventType,

    LoginName,

    HostName,

    NTUserName,

    NTDomainName,

    Success,

    FullLog)

    VALUES

    (

    CAST(CAST(@message_body.query('/EVENT_INSTANCE/PostTime/text()') AS VARCHAR(64)) AS DATETIME),

    CAST(@message_body.query('/EVENT_INSTANCE/EventType/text()') AS VARCHAR(100)),

    CAST(@message_body.query('/EVENT_INSTANCE/LoginName/text()') AS VARCHAR(100)),

    CAST(@message_body.query('/EVENT_INSTANCE/HostName/text()') AS VARCHAR(100)),

    CAST(@message_body.query('/EVENT_INSTANCE/NTUserName/text()') AS VARCHAR(100)),

    CAST(@message_body.query('/EVENT_INSTANCE/NTDomainName/text()') AS VARCHAR(100)),

    CAST(CAST(@message_body.query('/EVENT_INSTANCE/Success/text()') AS VARCHAR(64)) AS INTEGER),

    @message_body)

    END

    END

    COMMIT TRANSACTION

    END

    GO

  • I'd think sa has access to everything if it exists...

    if you don't filter by application name, your hours using the ERP will be inflated for developers who connect with SSMS to do stuff on the server.

    for this part:

    system.dbo.USERS

    do you really have a database named [system], which has a table dbo.USERS? could that be a typo?

    i guess you are assuming that a login on the server must be spelled the same as in your table?

    Lowell


    --help us help you! If you post a question, make sure you include a CREATE TABLE... statement and INSERT INTO... statement into that table to give the volunteers here representative data. with your description of the problem, we can provide a tested, verifiable solution to your question! asking the question the right way gets you a tested answer the fastest way possible!

  • also this part:

    'The service queue "LoggingQueue" is currently disabled.'

    you have to kick everyone off of the database to run the script to set up the queue; exclusive access is required. after that the proc will run fine. same thing happened to me because i had two windows open to my dev server's sandbox where i tested the code.

    Lowell


    --help us help you! If you post a question, make sure you include a CREATE TABLE... statement and INSERT INTO... statement into that table to give the volunteers here representative data. with your description of the problem, we can provide a tested, verifiable solution to your question! asking the question the right way gets you a tested answer the fastest way possible!

  • thanks for your help.

    i'm looking on different approach and i will update later.

  • If you're looking at alternatives, you might look into a Server Side trace as mentioned in

    http://www.sqlservercentral.com/Forums/Topic909777-146-1.aspx

    I got one started for my Logins (and Logouts) based upon the information here.

    Steve

  • yes this is one of my thought.

    the question is when working with the profiler for logon and logout event,

    how i can calculate to actual time that the user spent in the erp per day and make it reliable results?

    THX

  • That is the beauty of using server side traces, you don't use profiler. Instead, you execute an sp_trace_create statement to create a trace to a trace file, execute a number of sp_trace_setevent statements to set exactly what you want to capture and for which events (Login and Logut in your case) and sp_trace_setstatus statements to start and stop the trace. Once the trace is stopped, you can select into a table from ::fn_trace_gettable the fields that you have captured.

    Once you have it in a table, you can do some selects to get the Login and Logout date/time and perform calculations. If you capture Event Class (Login = 14 and Logout = 15), SPID and Login Name, you can identify the information you need to do the calculations.

    I always have on trace running all the time but just before midnight I start an new trace and stop the old one and insert from the old one into a table. I have set up a table that has Trace Tracking information so that it is totally automated and I can see if any problems occured.

    Steve

  • steve block (7/26/2010)


    That is the beauty of using server side traces, you don't use profiler. Instead, you execute an sp_trace_create statement to create a trace to a trace file, execute a number of sp_trace_setevent statements to set exactly what you want to capture and for which events (Login and Logut in your case) and sp_trace_setstatus statements to start and stop the trace. Once the trace is stopped, you can select into a table from ::fn_trace_gettable the fields that you have captured.

    Once you have it in a table, you can do some selects to get the Login and Logout date/time and perform calculations. If you capture Event Class (Login = 14 and Logout = 15), SPID and Login Name, you can identify the information you need to do the calculations.

    I always have on trace running all the time but just before midnight I start an new trace and stop the old one and insert from the old one into a table. I have set up a table that has Trace Tracking information so that it is totally automated and I can see if any problems occured.

    Steve

    with a trace file can you have it output the text data to a varchar(max) column? Profiler creates a varchar(4000) i think and i always get truncated queries when outputting to a table

  • I'm really not sure but you could try it. You could also ask that question in the other thread I provided. I know there were some experts there.

    What are you trying to capture from the Data field that is not in one of the other fields?

    Steve

  • how i can write this logon trigger that if i the user have an error in the trigger his logon processes will still be successfully but i will be notified with an error.

    THX

    CREATE TRIGGER UTRIG_CAPTURE_PRIORITY_LOGINS

    ON ALL SERVER WITH EXECUTE AS SELF

    FOR LOGON

    AS

    BEGIN

    BEGIN TRY

    if (ORIGINAL_LOGIN() in (select reverse(USERLOGIN) from system.dbo.USERS)) and (select count(*) from master.sys.sysprocesses where loginame = ORIGINAL_LOGIN() and hostname = HOST_NAME())= 0 and not(HOST_NAME() = 'TEST-SQL')

    begin

    INSERT INTO Audit_Logging.dbo.TBL_SQL_LOGON_LOGOUT_AUDIT (LOGIN_NAME,HOST_NAME,LOGON_DATE) values (ORIGINAL_LOGIN(),HOST_NAME(),GETDATE())

    end

    END TRY

    BEGIN CATCH

    --ALERT ME BUT STILL ALOW LOGON

    END CATCH

    END

Viewing 15 posts - 1 through 15 (of 18 total)

You must be logged in to reply to this topic. Login to reply