Question
· Mar 11, 2016

Determine currently used service

I want to determine what service (eg. %Service_Console) is used for current process.

I can probably use some workarounds, i.e.

  • Is %request object present
  • Does $Device  contain |TRM|
  • etc

But is there any centralised way to get current service?

Discussion (7)1
Log in or sign up to continue

One solution would be to look at the audit database. It's not pretty, but there might not be any other way.

 

ClassMethod GetLoginService() As %String
{
    New $Namespace
    Zn "%SYS"
    
    Set tService = ""
    
    // Ensure that login events are being audited.
    Set tLoginEvent = ##class(Security.Events).Get("%System","%Login","Login",.tProps)
    If '$Get(tProps("Enabled")) {
        // Querying the audit DB probably won't do any good.
        Quit tService
    }
    
    // Warning: on systems with a lot of activity, this query might take a long time.
    // It might be worth filtering by recent UTCTimeStamp, assuming processes won't be that long-running.
    Set tRes = ##class(%SQL.Statement).%ExecDirect(,
        "select top 1 EventData from %SYS.Audit "_
        "where EventSource = '%System' and EventType = '%Login' and Event = 'Login' and PID = ? "_
        "order by UTCTimeStamp DESC, SystemID DESC, AuditIndex DESC",$Job)
    
    Set tHasResult = tRes.%Next()
    If (tHasResult) {
        Set tData = tRes.%Get("EventData")
        //NOTE: This makes assumptions about the format of EventData.
        //Particularly, that it looks something like:
        /*
        Service name:       %Service_Bindings
        Login roles:        %All
        $I:                 |TCP|1972|15396
        $P:                 |TCP|1972|15396
        */
        //
        Set tFirstLine = $Piece(tData,$c(13,10))
        
        //Presumably "Service name:" might be localized, but %Service_<something> would not be.
        Set:tFirstLine["%Service" tService = "%Service"_$Piece(tFirstLine,"%Service",2)
    }
    Quit tService
}

 

Note: if your application is using Caché security correctly, you'd probably need to define a privileged routine application to allow access to Security.Events and the audit database.