Skip to main content

I want to write "total transfer time" to the destination as an attribute. When i process feature through "http caller" for each feature fme log writes "Total transfer time" in Log window. But this data I cannot extract, but somehow fme is getting this duration time, i need this time to write to destination. How can I extract this info. please help me. i pasted below my fme log window texts. please look for "

total transfer time: '3.058 seconds' in below log.

 

HTTPCaller_2(HTTPFactory): HTTP/FTP Transfer: Downloading resource 'https://gisnet.cable.comcast.com/eGisCoeServices/api/CC_MULTI_HFC_PRX_ANLYS_CORE_ERT?distance=2000&solvetype;=fiber&jobcost;=n&hfctype;=fspl&routecount;=1&xycoords;=-119.393773%2C36.545843' to internal memory buffer

HTTPCaller_2(HTTPFactory): HTTP transfer summary - status code: 200, download size: '12889 bytes', DNS lookup time: '0 seconds', total transfer time: '3.058 seconds', url: 'https://gisnet.cable.comcast.com/eGisCoeServices/api/CC_MULTI_HFC_PRX_ANLYS_CORE_ERT?distance=2000&solvetype;=fiber&jobcost;=n&hfctype;=fspl&routecount;=1&xycoords;=-119.393773%2C36.545843'

HTTPCaller_2(HTTPFactory): HTTP/FTP Transfer: Downloading resource 'https://gisnet.cable.comcast.com/eGisCoeServices/api/CC_MULTI_HFC_PRX_ANLYS_CORE_ERT?distance=2000&solvetype;=fiber&jobcost;=n&hfctype;=fspl&routecount;=1&xycoords;=-119.394293%2C36.545597' to internal memory buffer

HTTPCaller_2(HTTPFactory): HTTP transfer summary - status code: 200, download size: '15279 bytes', DNS lookup time: '0 seconds', total transfer time: '8.222 seconds', url: 'https://gisnet.cable.comcast.com/eGisCoeServices/api/CC_MULTI_HFC_PRX_ANLYS_CORE_ERT?distance=2000&solvetype;=fiber&jobcost;=n&hfctype;=fspl&routecount;=1&xycoords;=-119.394293%2C36.545597'

HTTPCaller_2(HTTPFactory): HTTP/FTP Transfer: Downloading resource 'https://gisnet.cable.comcast.com/eGisCoeServices/api/CC_MULTI_HFC_PRX_ANLYS_CORE_ERT?distance=2000&solvetype;=fiber&jobcost;=n&hfctype;=fspl&routecount;=1&xycoords;=-119.393318%2C36.546466' to internal memory buffer

HTTPCaller_2(HTTPFactory): HTTP transfer summary - status code: 200, download size: '36988 bytes', DNS lookup time: '0 seconds', total transfer time: '3.135 seconds', url: 'https://gisnet.cable.comcast.com/eGisCoeServices/api/CC_MULTI_HFC_PRX_ANLYS_CORE_ERT?distance=2000&solvetype;=fiber&jobcost;=n&hfctype;=fspl&routecount;=1&xycoords;=-119.393318%2C36.546466'

HTTPCaller_2(HTTPFactory): HTTP/FTP Transfer: Downloading resource 'https://gisnet.cable.comcast.com/eGisCoeServices/api/CC_MULTI_HFC_PRX_ANLYS_CORE_ERT?distance=2000&solvetype;=fiber&jobcost;=n&hfctype;=fspl&routecount;=1&xycoords;=-119.394295%2C36.546251' to internal memory buffer

HTTPCaller_2(HTTPFactory): HTTP transfer summary - status code: 200, download size: '40619 bytes', DNS lookup time: '0 seconds', total transfer time: '4.15 seconds', url: 'https://gisnet.cable.comcast.com/eGisCoeServices/api/CC_MULTI_HFC_PRX_ANLYS_CORE_ERT?distance=2000&solvetype;=fiber&jobcost;=n&hfctype;=fspl&routecount;=1&xycoords;=-119.394295%2C36.546251'

HTTPCaller_2(HTTPFactory): HTTP/FTP Transfer: Downloading resource 'https://gisnet.cable.comcast.com/eGisCoeServices/api/CC_MULTI_HFC_PRX_ANLYS_CORE_ERT?distance=2000&solvetype;=fiber&jobcost;=n&hfctype;=fspl&routecount;=1&xycoords;=-119.395492%2C36.545583' to internal memory buffer

HTTPCaller_2(HTTPFactory): HTTP transfer summary - status code: 200, download size: '4928 bytes', DNS lookup time: '0 seconds', total transfer time: '2.434 seconds', url: 'https://gisnet.cable.comcast.com/eGisCoeServices/api/CC_MULTI_HFC_PRX_ANLYS_CORE_ERT?distance=2000&solvetype;=fiber&jobcost;=n&hfctype;=fspl&routecount;=1&xycoords;=-119.395492%2C36.545583'

There's no easy way of doing this without whipping out Python, I think. Here's a way:

Set the following Python startup script:

import fmeobjects
import re

def fme_log_callback(severity, str):
    match = re.search(r"total transfer time: '(a\d\.]+) seconds'", str)
    if match:
        global last_http_caller_duration
        last_http_caller_duration = match.groups() 0]

fmelog = fmeobjects.FMELogFile()
fmelog.setCallBack(fme_log_callback)

Directly after your HTTPCaller, insert a PythonCaller with the following code:

import fmeobjects

def GetLastHttpCallerDuration(feature):
    global last_http_caller_duration
    if last_http_caller_duration: 
        feature.setAttribute('last_http_caller_duration', last_http_caller_duration)

Configure the PythonCaller as follows:

0684Q00000ArLBIQA3.png

Your feature will now have a new attribute called "last_http_caller_duration" that will be the number of seconds spent on the last call.


The other way (without python) would be to parse the logfile, but admittedly the method provided by @david_r is much neater!


The other way (without python) would be to parse the logfile, but admittedly the method provided by @david_r is much neater!

The Python solution I posted above does in fact parse the logfile, but it does it in real-time rather than after the translation has ended.
The Python solution I posted above does in fact parse the logfile, but it does it in real-time rather than after the translation has ended.
Yes I understand that and was wondering if that is also the method to be used with the functions described here: https://docs.safe.com/fme/html/FME_Desktop_Documentation/FME_Workbench/Configuration/FME_END_PYTHON.htm

 

Personally not a big python user and find the documentation lacking any good examples.

 

 


Yes I understand that and was wondering if that is also the method to be used with the functions described here: https://docs.safe.com/fme/html/FME_Desktop_Documentation/FME_Workbench/Configuration/FME_END_PYTHON.htm

 

Personally not a big python user and find the documentation lacking any good examples.

 

 

I haven't seen the FMELogFile.setCallBack() function documented outside of the fmeobjects apidoc. I know both @takashi and I have posted a couple of answers here using it, other than that I haven't seen any examples or mention from Safe. Granted, that also applies to a lot of other stuff in the fmeobjects API.

 

Using callbacks can be confusing for beginners, so I can understand why it's not pushed too actively.

 


Thanks to David and Itay. It worked. Great!!

I used David's method. mmuuaahh


Before writing to you i used this python, (ha ha... this is very basic method)

from datetime import datetime
def FeatureProcessor(feature):
    t11 = feature.getAttribute("time1")    
    t21 = feature.getAttribute("time2") 
    t1 = datetime.strptime(t11, "%Y%m%d%H%M%S")
    t2 = datetime.strptime(t21, "%Y%m%d%H%M%S")
    t2 - t1
    # datetime.timedelta(0, 11102)
    day_delta=(t2 - t1).seconds
    feature.setAttribute("Time_taken", day_delta)





here i took two timestamper , before and after httpcaller and find the difference
in seconds. But i feel yours is better way. Thanks again Mr David
   
   

There's no easy way of doing this without whipping out Python, I think. Here's a way:

Set the following Python startup script:

import fmeobjects
import re

def fme_log_callback(severity, str):
    match = re.search(r"total transfer time: '(a\d\.]+) seconds'", str)
    if match:
        global last_http_caller_duration
        last_http_caller_duration = match.groups() 0]

fmelog = fmeobjects.FMELogFile()
fmelog.setCallBack(fme_log_callback)

Directly after your HTTPCaller, insert a PythonCaller with the following code:

import fmeobjects

def GetLastHttpCallerDuration(feature):
    global last_http_caller_duration
    if last_http_caller_duration: 
        feature.setAttribute('last_http_caller_duration', last_http_caller_duration)

Configure the PythonCaller as follows:

0684Q00000ArLBIQA3.png

Your feature will now have a new attribute called "last_http_caller_duration" that will be the number of seconds spent on the last call.

Best Answer

 

 


I wonder if syntax has changed for the solution.

I wanted to get the ProcessID from the message that contains START and I get an error on ProcessFeature.

Here's my error message

0684Q00000ArL58QAF.png

My workspace is basically a Creator with one object, a PythonCaller and an inspector.

Here's my code for the startup Python script

 

import fmeobjects
import re

def fme_log_callback(severity, str):
     match = re.search(r"ProcessID: (\d+)", str)
     if match:
        global processID
        processID = match.groups()b0]

fmelog = fmeobjects.FMELogFile()
fmelog.setCallBack(fme_log_callback)

Here's my code in the Python Caller.

import fmeobjects

def GetProcessID(feature):
global processID

    if processID:
         feature.setAttribute('pid', processID)

I'd also like to get from the log, messages that contain "FME Session Duration" and the "END". From each line, I'll parse off the translation details that I need to store as translation history. Would the Callback method work for the END log message? @david_r, your answer in this thread is so far the best and closest solution I have found so far.


In the modern FME, the LogMessageStreamer could be an option.

e.g.


In the modern FME, the LogMessageStreamer could be an option.

e.g.

@takashi thanks for your response. I am already using the LogMessageStreamer for my httpcallers - I have 120 of these httpcallers in my workspace and I'm capturing the total transfer time for each transformer. I need the history log of the entire translation. However, as far as I know, LogMessageStreamer does not capture the log streams from the beginning and the end of the translation where START, FME Session Duration and END are. Perhaps I should create a new question, since this is not really the same. The python solution is probably the answer but I can't seem to make it work.


I haven't seen the FMELogFile.setCallBack() function documented outside of the fmeobjects apidoc. I know both @takashi and I have posted a couple of answers here using it, other than that I haven't seen any examples or mention from Safe. Granted, that also applies to a lot of other stuff in the fmeobjects API.

 

Using callbacks can be confusing for beginners, so I can understand why it's not pushed too actively.

 

I can relate to what @itay said about documentation and as far as Safe's examples, they have a Nov 2019 blog update with three samples using callback from @daveatsafe. To your point David on how callbacks can be confusing, in spite of these samples from Safe, I still can't accomplish what I needed to do to retrieve three specific log messages into my translation. So I'm relying on your sample and callback documentation to solve my problem. Not there yet, so any ideas are welcome.


I wonder if syntax has changed for the solution.

I wanted to get the ProcessID from the message that contains START and I get an error on ProcessFeature.

Here's my error message

0684Q00000ArL58QAF.png

My workspace is basically a Creator with one object, a PythonCaller and an inspector.

Here's my code for the startup Python script

 

import fmeobjects
import re

def fme_log_callback(severity, str):
     match = re.search(r"ProcessID: (\d+)", str)
     if match:
        global processID
        processID = match.groups()b0]

fmelog = fmeobjects.FMELogFile()
fmelog.setCallBack(fme_log_callback)

Here's my code in the Python Caller.

import fmeobjects

def GetProcessID(feature):
global processID

    if processID:
         feature.setAttribute('pid', processID)

I'd also like to get from the log, messages that contain "FME Session Duration" and the "END". From each line, I'll parse off the translation details that I need to store as translation history. Would the Callback method work for the END log message? @david_r, your answer in this thread is so far the best and closest solution I have found so far.

Two things that jump out to me:

  1. In the first block, if 'match' is undefined, then 'processID' will never be defined and you'll get the error in the screenshot
  2. In the second block, there's a indentation error on line 4, but perhaps it's only a forum issue?

I wonder if syntax has changed for the solution.

I wanted to get the ProcessID from the message that contains START and I get an error on ProcessFeature.

Here's my error message

0684Q00000ArL58QAF.png

My workspace is basically a Creator with one object, a PythonCaller and an inspector.

Here's my code for the startup Python script

 

import fmeobjects
import re

def fme_log_callback(severity, str):
     match = re.search(r"ProcessID: (\d+)", str)
     if match:
        global processID
        processID = match.groups()b0]

fmelog = fmeobjects.FMELogFile()
fmelog.setCallBack(fme_log_callback)

Here's my code in the Python Caller.

import fmeobjects

def GetProcessID(feature):
global processID

    if processID:
         feature.setAttribute('pid', processID)

I'd also like to get from the log, messages that contain "FME Session Duration" and the "END". From each line, I'll parse off the translation details that I need to store as translation history. Would the Callback method work for the END log message? @david_r, your answer in this thread is so far the best and closest solution I have found so far.

The main issue is that when the Python startup script executes, the process ID has already been written to the log file, meaning that those lines will never be captured by either the callback function or the LogMessageStreamer (which uses the callback internally).

If you need to extract the process ID, you could consider reading and parsing the log file in the startup script, e.g.

import fme
with open(fme.logFileName, 'r') as f:
    contents = f.read()
    # use regex to search for process ID in contents

The main issue is that when the Python startup script executes, the process ID has already been written to the log file, meaning that those lines will never be captured by either the callback function or the LogMessageStreamer (which uses the callback internally).

If you need to extract the process ID, you could consider reading and parsing the log file in the startup script, e.g.

import fme
with open(fme.logFileName, 'r') as f:
    contents = f.read()
    # use regex to search for process ID in contents

Thanks for stating the main issue. The indention is a forum issue.

Thanks also for the code. More of a python issue at this point. I really need to retrieve a few lines of the log and bring it to my workspace to process. I got it as far as retrieving the line but I still need a few more answered questions to get it done.

 


I can relate to what @itay said about documentation and as far as Safe's examples, they have a Nov 2019 blog update with three samples using callback from @daveatsafe. To your point David on how callbacks can be confusing, in spite of these samples from Safe, I still can't accomplish what I needed to do to retrieve three specific log messages into my translation. So I'm relying on your sample and callback documentation to solve my problem. Not there yet, so any ideas are welcome.

Hi @salvaleonrp,

Thanks for your question! I almost missed your post here as I realized this Q&A is from quite some time ago and already has an accepted answer. For better visibility that will get you some more help, would you be open to posting a new question to the Forums with your issue, what you've tried, and where you're stuck? You can always link back to this question for context.

 

 

In the meantime, I'm not sure if perhaps the LogMessageStreamer might be a potential alternative to take a look at? Posting a new question also opens this up to users with experience with any new functionality in FME since 2017 that could perhaps solve this in a new way.

Reply