Problem/Motivation
Sometimes there are failures on Feeds imports and it is not always clear why or how these failures happened. For example:
- There are validation errors, but you are not sure why.
- When using the feature for cleaning up items that no longer exist on the source, it can happen that it cleans up items you didn't expect would be cleaned. Does that mean a bug on the source or in Feeds?
Proposed resolution
To get more insight in what happens during an import, it would be useful to have a detailed Feeds log system. This system would cover the following information:
- Which source data was used for the import?
- Per imported item, how did the source item look like after parsing?
- Which entities got created, updated or deleted? And which did fail to import?
Source data
The source data would be logged on the filesystem in a folder called:
private://feeds/logs/[import_id]/source/
Since fetching can technically happen multiple times per import, there could exist more than one logged source file per import.
Item data
The item data would be logged on the filesystem in a folder called:
private://feeds/logs/[import_id]/items/
Remaining tasks
Write fetched source data to a file.DONEWrite parsed items to files.DONEAutomated tests.DONEConfiguration options: for example, it would be useful to only enable logs for one specific feed type. Or to only log items that failed.DONE-
Deleting log entries:DONEDelete logged files when deleting a log entity.DONEAdd a button in the UI to manually delete a log entity.DONEAdd a button in the UI to manually delete all log entities for a single feed.DONEAutomatically cleanup all log entities when deleting the feed.DONEAutomatically cleanup all log entities after a certain amount of time.DONE
View logged files on a private file system.DONEDecide how to handle logs for imports that did not finish in a timely manner (see #58)DONE- Check if logged messages don't get double translated. If logging a translated message is unavoidable, see if translating it again can still be avoided. - Maybe fix in a follow-up
User interface changes
On the feed entity, a new tab called "Logs" would appear. Clicking on this tab reveals all imports that ran, with the following information:
- Import start time
- Import finish time
- Number of log entries for this import
- Source files
- A link called "View entries" which would link to a page where all log entries for that import can be viewed.
On the page for a single import, a table consisting of the following information would be displayed:
| Column name | Description |
|---|---|
| Entity ID | The ID of the entity that was involved. Can be empty if the entity failed to import. |
| Entity type | The type of the entity that was involved. |
| Entity label | An alternative for identifying the entity, because the entity may not exist yet or it may have been deleted. |
| Operation | Type of the operation, for example "created", "updated", or "cleaned". |
| Message | The log message. |
| Time | Time of when the event occurred. |
| Source item | A link to the logged source item. Maybe the link would open a modal in which you would see the raw item data. |
API changes
The State object would get a method called report(). This method would increase the counters for the operation that happened. For example "updated".
Reporting an operation
Code can report an operation in a form something like this:
$state->report(StateType::UPDATE, $message, [
'feed' => FeedInterface $feed,
'item' => ItemInterface $item,
'entity' => EntityInterface $entity,
'item_id' => $this->identifyEntity($entity), // See patch from #3063055: Allow parsers and event subscribers to mark an item as invalid.
]);
This would replace code like $state->updated++ and $state->setMessage().
Code on the State object would look something like this:
/**
* Reports a processed item.
*
* @param string $code
* What happened to the imported item.
*/
public function report($code, $message, array $context = []) {
$this->$code++;
if (isset($context['feed'] && $context['feed'] instanceof FeedInterface)) {
$feed = $context['feed'];
unset($context['feed']);
$this->eventDispatcher->dispatch(FeedsEvents::REPORT, new ReportEvent($feed, $code, $message, $context));
}
}
Data model changes
-
A new content entity type called "feeds_import_log"
This entity type will act as the container for a series of log entries. On each import, a new instance will be created. On this entity type are stored:- Import ID
- Feed ID
- Import start time
- Import end time
- The user under which the import is ran (can be different from who triggered it)
- Path to logged source files
-
A new database table called "feeds_import_log_entry"
This table will contain the individual log entries. One entry per imported, failed or cleaned item would exist. There is a reference to the feeds_import_log entity and a reference to the feed entity.
Original report by PunamShelke
HI,
After feeds getting import, it will show the success message and count of imported content and for unimported content it will through as warning with fields name.....
I have to maintain the log of unimported record for each feed.
now what i am planing to add whatever the warning and errors are there that i need in any txt file so i have the log report for import .....
I am planing to build this things as a patch of new feature....
is this feature is use full, or needs to do some changes?
| Comment | File | Size | Author |
|---|---|---|---|
| #82 | feeds-2907721-feeds_log-8.x-3.0-beta2-oct31.patch | 201.93 KB | megachriz |
| #76 | 2907721-item_id-added-to-log-entry.png | 376.8 KB | megachriz |
| #50 | feed-type-log-settings.png | 287.35 KB | megachriz |
Issue fork feeds-2907721
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
punamshelkeHi,
I am going to put patch and the support modules..
Through which we can have report log as in currently we have in drupal 7 (feeds_tamper)
Any suggestions regarding this, please mention......
Thanks
Comment #3
megachrizIt would certainly be useful to have an overview of items that failed to import. There is a Feeds log in the D7 version. I'm not sure why it was removed in the D8 version by twistor in this commit. I assume though because the Feeds log in the D7 version has some overlap with the core database log and some people reported that they don't want these logs in the database (see #1367044: Use syslog.module for feeds_log and/or an option to disable log).
Other log issues (D7):
#2364103: Feeds error log crashes when log messages are too long
#2827751: Log warning message when a parser suddenly returns empty results
#1037188: Log exceptions that are thrown when trying to fetch from a HTTP source.
#2815907: Add option to debug imported items
It would be good if we could come up with a design plan for bringing this feature back. How does the Migrate module handles this? Maybe we could use that as an idea.
Comment #4
punamshelkeHi,
Thank For reply
I have implemented the feeds log feature it is similar to drupal 7
This is working fine, i have attache some screenshot please check it
and let me know the changes
Comment #5
megachrizThis looks awesome!
Suggestions for improvements:
This way you could see for question 5 from your image example that it did not have a roles value.
Comment #6
megachrizIn the past I have also been thinking about how the State class could be improved. This class does not collect all the error messages and keeps track of everything happening during the import. It would be great if somehow this class could be involved with this log process, rather than adding a new subsystem. I had been playing with some ideas for the State class for an other project that used a replacement for Feeds (as Feeds for D8 wasn't usable at the time). See attached.
Code snippet from the module:
Comment #7
punamshelkeThanks
I will implement this suggestions....
Comment #8
punamshelkeThis is the patch to invoke the feeds log functionality...
Comment #9
megachrizFeeds doesn't invoke any hooks at the moment. It would be better if this feature would be handled through events.
I'm seeing a
$this->loggerhere. Wouldn't it possible to hand over the task of logging unimported items to that object?Comment #10
punamshelkeThanks
I will look in to the commerce_log module
Comment #11
megachrizClosed #2981100: show failed imports on results page as a duplicate.
Changing title, so that the issue is hopefully found easier.
Comment #12
anybodyFeeds_log is exactly what we need in feeds. This or similar functionality should definitely become part of feeds. We just ran into the situation where 2 items were'nt imported but we couldn't find out why.
Plans in #9 look great!
Comment #13
vipul tulse commented@MegaChriz #9
Can you please suggest which event we can use here?
example : FeedsEvents::PARSE
Comment #14
anybodyPatch #8 now fails to apply. :(
Comment #15
hongpong commentedRe-roll of #8 to current head 8.x-3.x. I haven't tested it.
Comment #16
trickfun commentedMay be enough to create new event and put it inside catch exception statement in EntityProcessorBase.php file.
Something like:
so i can log also errors.
thanks
Comment #17
fishfree commentedCan this feature be backport to D7?
Comment #18
liquidcms commentedAwesome work. Thanks guys.
Also, might be useful to mention this required module in the original post: https://www.drupal.org/project/feeds_log
Comment #19
megachrizI'm working on a detailed Feeds log system. The log system would cover the following information:
I'm doing this work for a client, so I hope the client continues to support this work so that I'm able to finish it.
Let me know your thoughts!
Description
Source data
The source data would be logged on the filesystem in a folder called:
private://feeds/logs/[import_id]/source/
Since fetching can technically happen multiple times per import, there could exist more than one logged source file per import.
Item data
The item data would be logged on the filesystem in a folder called:
private://feeds/logs/[import_id]/items/
User interface
On the feed entity, a new tab called "Logs" would appear. Clicking on this tab reveals all imports that ran, with the following information:
On the page for a single import, a table consisting of the following information would be displayed:
Implementation
The State object would get a method called
report(). This method would increase the counters for the operation that happened. For example "updated".Reporting an operation
Code can report an operation in a form something like this:
This would replace code like
$state->updated++and$state->setMessage().Code on the State object would look something like this:
Report event
A see you see above, a new event is dispatched there. Here is a draft of the ReportEvent class:
Feeds Log module
A new module called "feeds_log", added to the Feeds project, would subscribe to the ReportEvent and log the data it receives from it.
It would also subscribe to:
The log collection for a single import would be stored in a content entity type called "feeds_import_log". On this entity type are stored:
Comment #20
megachrizHere is an initial implementation, so you can see where this is going. I've done some minimal testing and import reporting works at least if an import was succesful.
To do:
Feedback on the direction this is going, is of course welcome.
Comment #21
jamesdixon commentedI like the report function on the state object. It's like a Feeds specific version of Drupal log().
I worked with Feeds a lot in D7 and this would have helped me debug some problematic imports.
Having separate logs for the source and item is key. If a source isn't parsing the way you expect, having that source log is amazing.
Of course the items are also important to look at.
Haven't had a chance to test the patch but the UI you describe sounds great.
Comment #22
carolpettirossi commentedFirst of all, thanks for working on this feature request and thanks for this great module (Feeds).
I'm testing the patch from #20 and I know that it's not ready but I'm facing the error below on my existing drupal 9 setup. Is this expected?
These are the steps I've done:
1. Installed Feed log
2. Created a new feed of an existing feed type
3. Clicked on Save and Import
4. Error above was displayed.
Comment #23
megachriz@carolpettirossi
Great that you want to try it! If I look at my code I see I'm undecided on how to call the identifier for a new entity that failed to import and therefore has no entity ID. On one place in the code I call this "item_id", to designate the source item that failed to import, and on an other place I call this "entity_label", to hang a label on the entity that was in the process of getting created, but failed validation.
So if you replace all occurences of "item_id" with "entity_label" in the code, I think you will get past the error.
I hope my client gives me time again soon to continue this work. :)
Comment #24
carolpettirossi commented@MegaChriz,
Just wanted to add here that I haven't had time yet to test what you suggested, but I'll try during this week or early next week.
Comment #25
carolpettirossi commentedSorry about the delay. It took me longer than I expected in another task.
I had to do some adjustments in order to get the patch working:
- replaced all
item_idbyentity_labelas per @MegaChriz suggestion on #23- adjusted feeds_import_log_entry schema. entity_id can be null if the entity failed to import so I changed 'not null' to FALSE
- entity_id is INT, so I updated
addLogEntryWith the adjustments above I could get it working for some simple scenarios
- Created
- Skipped because the entity already exists.
- Failed because it failed to validate
I'll ask my team help to validate it and add more feedback or patch updates here.
Comment #26
carolpettirossi commentedSmall update to log the file path instead of 'abc'
Comment #27
carolpettirossi commented@MegaChriz,
I'm wondering how can we log the source item. I can see this column in the report/log however the
logItemfunction has not been implemented and I'm not sure what's your idea here.I probably can help with the implementation just need some guidance in the right direction.
Thanks
Comment #28
megachriz@carolpettirossi
Many thanks for helping on this issue! In the D7 version of Feeds there already exists code to log a source item, so my idea was to try to port that code. See
FeedsProcessor::exportObjectVars(). That method is called byFeedsProcessor::createLogEntry(), which is called when an exception occurs inFeedsProcessor::process().https://git.drupalcode.org/project/feeds/-/blob/7.x-2.x/plugins/FeedsPro...
Comment #29
carolpettirossi commentedThanks @MegaChriz.
I'll have a look as soon as I have more time allocated to this feature.
Re-rolling #26 cause it failed.
Comment #30
trickfun commentedGreat work.
Patch #29 works fine but is difficult to find where is the into source.
May be useful to add 2 new columns into feeds_import_log_entry:
The unique field value set into configuration of the feed.
The json encoded data of the source.
I think that with this information is easy debug the process and find error into source.
Comment #31
megachrizI've updated the issue summary.
Hopefully I'll have time again to continue this work soon.
Comment #32
socialnicheguru commentedpatch no longer applies to latest feeds dev.
Comment #33
elvin - albania drupal developeris there any development on this? i was never able to reach the log of which GUID's failed to import. this would help a lot to troubleshoot problems from the source and fix them there, especially for ongoing synchronizations. thanks in advance
Comment #35
irinaz commentedComment #36
danharper commentedI can confirm this patch isn't working anymore, is it still required?
It looks like the EntityProcessorInterface has changed.
Cheers Dan
Comment #37
danharper commentedMy mistake, adding a patch that does apply.
Comment #38
liquidcms commented#37 does not apply to alpha10, is it meant to be on: 8.x-3.x-dev?
Comment #39
liquidcms commentedok, all sorted out. I was trying to figure out why my code to set the unique value wasn't working (#3232024: How to set Unique field?). On a whim i set force update and unchecked to authorize that user has access - and then everything worked. Figured it would have been great to have some sort of error msg to simply state i didnt have access - that brought me back to this post which i was familiar with from a year ago and realized the Feeds Log module never worked for me.
A little clean up:
- remove the old separate feeds_log module that i had enabled
- switch feeds to latest -dev
- apply patch from #37
- enable the log module which is now included with feeds
to test: set my force/authorize settings back as they were and re-import - and i now see log entire stating author of node didnt have access to update.
all good. Thank so much for this work.
Comment #40
webdrips commentedThanks for the updates, but note #37 is not ideal because it uses a different table name and different columns than the old standalone feeds_log module. Also I didn't really have a chance to review, but I wonder if a hook_uninstall might be warranted? Perhaps there is nothing to uninstall since the tables should be removed. Not sure but just in case it's needed...
Something like
Secondly, I suppose because I have the language core module installed, I was getting an error importing a feed because there was no uuid column, so I added this to the .install to address the issue:
In my case I had to uninstall the old feeds_log module, then re-install the new module in 37 to get this patch to work on the feeds dev version.
I really appreciate that you can click the "View entries" to see additional details on why something failed.
I wonder if, from a UI perspective, it might not make more sense though to add a separate tab called log-messages or something similar. I didn't find that link super intuitive until I clicked it.
Comment #41
anybodyHi all, I just became maintainer of feeds_log module to create the Drupal 9 release.
The initial maintainer wrote on the module page at https://www.drupal.org/project/feeds_log:
As a first step, can we perhaps have these hooks added in feeds to allow to solve this in contrib cleanly? Of course we can rename them or whatever, but I guess adding hooks to allow contrib interaction won't do any harm?
But they should definitely be renamed to contain "feeds" ... "hook_delete_log" definitely is not cool ;D
Do you agree?
Comment #42
anybodyAs of #42 I rerolled the patches from and renamed the hooks to work with 2.x of https://www.drupal.org/project/feeds_log
I changed my mind:
!THIS PATCH SHOULD NEVER BE COMMITTED!
Instead, I'd vote for a solution in feeds directly and deprecate the module once that's done! :)
Anyway, clean events for certain types of actions still wouldn't be wrong in feeds to allow contrib interaction. ;)
Contact me, if any changes in feeds_log are required in the meantime.
Comment #44
megachrizThe Feeds log module has become a bit more usable:
Still requires:
Screenshots:
Overview of imports that ran
Overview of processed items from a single import
Comment #45
trickfun commentedHi MegaChriz,
great job :-)
Patch works fine!!
Why not separate failed items from success one?
May be useful to provide a filter in view entries log page to filter failed items.
Another options may be create a page with failed items only.
What do you thing?
Thank you in advance
Comment #46
megachriz@trickfun
Thanks for giving it a try! I already added the option to filter on failed items. Did you use the code from the issue fork "2907721-log-items-that"? It has more features than the patch from #37.
At a later stage I plan to add configuration for which operations to create log entries. So in that case you can configure it to only log failed items.
Comment #47
megachrizIt is now possible to delete a single logged import in the UI.
Next step: add a button in the UI to delete all logged imports for a single feed.
Comment #48
webdrips commented@MegaChriz thanks for working on this! Do we have a timeline for the next dev release?
Comment #49
megachriz@webdrips
I hope my client allows to me finish this feature in the nearby future. After that, I'd like to test this Feeds Log module on a real website for a couple of weeks to maybe catch some bugs. When I find no serious issues, then I'll commit this to the dev version.
Today I've implemented a simple automatic cleanup of logs: logs are cleaned up after a week using cron. I also made viewing the logged files when using the private filesystem possible.
Next step is to add configuration options per feed type. It can be useful to only enable logs for certain feed types. Or to only log items that failed.
Comment #50
megachrizI implemented the option to enable/disable logging per feed type. How it works now is that when you haven't configured logging for a feed type yet, all gets logged for that feed type. Is that a good default? Because I was thinking that it would be nice that logging starts as soon as you enable the module. The alternative would be that when you enable the module, nothing gets logged initially. In that case you would need to update the configuration for each feed type.
The logging settings form for a feed type:

Let me know what you think should be the default:
Comment #51
anybodyI'd vote for (1) as I'd see it as expected behavior. Otherwise, you won't even look for the module. And if things get too noisy, you can easily disable logging.
But I'm sure both would be fine, so don't make the decision too hard for you.
Comment #52
trickfun commentedI agree with this default.
thank you
Comment #53
megachrizUninstall bug fixed
I had waited with setting this to "Needs review" because there was a bug when you tried to uninstall the Feeds Log module: feed types could get deleted. That bug is fixed now in #3092823: Uninstalling Feeds Tamper will result into feeds type getting deleted.
Running the module for 6 days: some numbers
I've been running this log module on a client site for nearly a week now. It has already been helpful because once I could see why something wasn't imported. Some numbers about on how much space the logs take up:
Cleaning up old logs
In a few days I can check how well cleaning up old logs will go. I've configured the log module to clean up logged imports that are older than a week (the default setting).
Issue: translated messages get logged
There is one known issue and that is that sometimes already translated messages get logged. When viewing the logs, these messages go through the translation layer again. I've been trying to fix that but I feel that opens an other can of worms, so I think it would be better to fix that in an other issue.
It would be great if others want to try the module too and see if you find any issues with it. I'll be monitoring the logs on that client site for at least some more weeks before I would commit this.
Comment #54
trickfun commentedSorry for my stupid question but how can i use this version with composer?
thank you
Comment #55
webdrips commented@MegaChriz can we get a patch to review? I believe I tried using the MR diff as a patch, and it broke the module at the time I tried it anyway.
Comment #56
megachriz@webdrips
Great that you want to give a try! I believe a patch should be completely the same as the plain diff: https://git.drupalcode.org/project/feeds/-/merge_requests/61.diff
Did you try to apply it to the latest dev? I guess it won't apply on Feeds 8.x-3.0-beta1.
@trickfun
I've been running it on a site for a few weeks now. I should recheck how the logs look like now, haven't checked them in a while. One thing I did realize is that not all messages that are logged in the "regular" log (like the database log, when using the dblog module) during an import can be found back in the log for the specific feed. For example: I noticed that messages for references that were not found don't appear in the feed log.
Comment #57
trickfun commentedThank you MegaChriz
patch works fine!!
one request more to complete your great job.
i need to import thousands of images with hundreds of error. images that are not there and so on...
what do you think to add "unique" field value in log table?
with this new column you can view directly the entity in error.
i think when importing commerce products or variations. views the sku in log table will be great.
thank you
Comment #58
megachriz@trickfun
In the column "entity" you can see which entity the import tried to create/update/clean, but it sounds like a good idea to have a column where you see the value for the target you marked as unique as well. You do can access that data if you configure it to log the source items.
Testing
I've been running the logs on a site for some time now. One thing I noticed today is that two logs from a few weeks ago were not cleaned up. Both of these were logs for imports that did not finish. I wonder what to do about these, because it is technically possible an import runs longer than a week, for example if you run cron only once a week.
I noticed that on the filesystem the logs take about 1.1GB of space. They took nearly 1GB of space when the logs were turned on for six days (see #53). I configured to keep the logs for 7 days, so that file size looks to be consistent.
The space the logs take in the database now is 2.2MB for 656 logged imports. That is still a pretty low amount of space.
Comment #59
kyuubi commentedHi everyone,
Trying to update to beta1 but we seem to have this patch in prod that doesn't apply.
Does anyone have a patch that could apply cleanly to beta1?
Thanks!
Comment #60
megachriz@kyuubi
This is written on top of the dev version, might be a lot of work to make it apply to beta1 too since it is a large amount of code.
I have been planning to release beta2, just need to take some time to write proper release notes first. And I'm also actively using the dev version on some sites in the hope to detect possible regressions of recent changes. Nothing too disturbing so far, it's more like that I found some regressions lately that already have been there for multiple releases.
In other words, you could try this code in combination with the latest dev, looks like a better effort to me than trying to make it compatible with beta1.
Comment #61
ptmkenny commentedApplying the merge request as a patch no longer works with the most recent dev branch on June 30: dev-3.x dfabf91.
Comment #62
megachrizI've rebased the code on the latest dev.
Comment #63
trickfun commentedI can't apply patch to 6d17e51
thank you
Comment #64
kyuubi commentedThanks MegaChriz!
We'll keep using the beta1 for now and might upgrade when this makes it in given everything works well currently.
Comment #65
trickfun commentedAnyone can install patch with composer?
i can't.
diff doesn't work
thank you
Comment #66
unstatu commentedSuccessfully applied the Merge Request in the beta2 version.
I have also tested the feature and it works great. Thanks all for the hard work. It's a really useful one.
Comment #67
unstatu commentedI have found an error in case that the entity_label is longer than 255 characters. The database insert/update operations throw an error in that case.
I have refactored a little bit the code and added an extra sanitization code (https://git.drupalcode.org/issue/feeds-2907721/-/merge_requests/1)
Comment #68
megachriz@unstatu
Thanks for your contribution, I've added a check for the existance of
$entry['item']before trying to truncate it.Also rebased the code on the latest dev. Attached a patch for beta2.
Comment #69
megachrizHm, some tests are failing after rebasing the code. I'll look into it.
Comment #70
megachrizComment #71
megachrizGreat, tests are passing again! Back to "Needs review".
Comment #72
alae.akalayHi,
I've been trying to apply the patch with composer and I'm getting the following error:
But after running composer command I checked the feeds contrib module folder and I can see the diff applied, how is that possible that I'm getting error on the composer command?
Will appreciate any help or feedback on this.
Thanks
Comment #73
trickfun commentedWhy don't you use #68 patch ?
it is work.
Comment #74
alae.akalayThanks @trickfun, #68 works fine for me now.
Comment #75
rdworianyn commentedCleanly applied to Beta2 and all is working well. Just saved me so much time tracking down a trivial error!!
Comment #76
megachrizI found a way to clean up old logs for imports that never finished! They get cleaned up after some time when a newer import for the same feed exist. This should be a good enough indicator that the older import is no longer running because it is discouraged to have two imports for the same feed active at the same time.
@trickfun
I've added this feature now! You can test this if you apply the changes from the issue fork to the latest dev. The text does get truncated if it is longer than 255 chars.
This is how it looks like:
Feedback welcome!
Comment #77
trickfun commentedThank you MegaChriz.
It's work very well.
Now is clear what goes in error. :-)
Comment #78
megachrizI've made a few updates to the latest code:
Comment #79
trickfun commentedThank you MegaChriz.
Great Job!!
con you provide the patch for beta 2?
thank you in advance
Comment #80
megachriz@trickfun
Here is patch against beta2. Not tested this one myself though. I hope to release beta3 in couple of weeks though or at least before December 14 when Drupal 10.0 gets released. So testing this in combination with the latest dev would be more valuable to me.
Comment #81
trickfun commentedSorry but i get this error.
Could not apply patch!
Comment #82
megachrizOops, after applying the changes on top of beta2, I created a diff against dev instead of beta2.
New patch for beta2. :)
Comment #85
megachrizI finally merged the code! It will be included in the next Feeds release: 8.x-3.0-beta3. That release is planned to happen before December 14, when Drupal 10.0 gets released. That release will also be the first one compatible with Drupal 10.
#3132198: Clean queue tasks when unlocking a feed to prevent potential data loss is the only must have left for the next release.
I think that this does mean that https://www.drupal.org/project/feeds_log (maintained by @Anybody and others) now is obsolete as it has the same name as the module that is now part of Feeds.
Comment #86
trickfun commentedThank you MegaChriz
Great job!!