Indexing of photos and videos can take long on a Synology and is resource (mostly CPU, but also a bit on the harddisks) intensive. Your Synology desktop (DSM 6.x) might give you an overview about what's happening, but sometimes you want some more detail. If you understand a little bit of Linux OS and want some more insight on command line (CLI) interface, then this script is for you!
The script shows you the actual state of the database, what indexing related processes are running and on what files these processes worked on.
Example:
DATABASE STATUS on (2017-10-30 16:07:34) media | count | lastprocessed Music | 2461 | /volume1/music/SomeMusicFile.mp3 Photos | 762 | /volume1/photo/SomePhoto.jpg Videos | 58 | /volume1/video/SomeVideo.mp4 Directories | 392 | /volume1/photo/SomeDir media | date | mdate Music | 2017-02-05 01:48:37 | 2016-10-22 22:15:24 Photos | 2009-01-06 21:34:54 | 2009-01-06 21:34:54 Videos | 2014-03-08 21:00:40 | 2012-08-21 13:22:34 Directories | 2015-01-09 15:30:41 | 2015-01-09 15:46:53 Showing real time file access of indexing/thumbnailing processes (5 sec interval, so some lines are missed): QUEUE STATUS Indexing queue 53 Photo conversion progress: 1103/1475 (75%), thumbnails: 2190/2934 (75%) Video conversion progress: 0/0 CURRENT PROCESSES postgresphoto 20.3 SELECT synoindexplugind 3.1 mediaparser synoindexd synothumb 0.0 /volume1/photo/SomePhoto.jpg synomkthumbd ffmpeg-thumb frecognition 25.0 /volume1/photo/SomePhoto.jpg UniversalSearch/fileindexd 0 UniversalSearch/synoelasticd 0 LAST DETECTED mediaparser NOTimplemented synoindexd NOTimplemented indexworkerd NOTimplemented synothumb /volume1/photo/SomePhoto.jpg synomkthumbd /volume1/photo/SomePhoto.jpg ffmpegthumb facerecognition /volume1/photo/SomePhoto.jpg fileindexd
This script is still in development, so some bugs may occur. However as all commands are read-only, no harm should be done to your system (of cause no garanties )
I'm very interested about any improvements!
#!/usr/bin/bash # # Nice Index Status # version 1.1 # # Last updated 2019-10-06 by RoBo # ToDo: # on nas within busybox #cat: /var/spool/conv_progress_photo: No such file or directory #cat: /var/spool/conv_progress_photo: No such file or directory #awk: cmd. line:1: fatal: division by zero attempted #./niceindexstatus: line 200: procopenfiles: command not found # some info # # PHOTO # Filename Max width or height (pixels) # SYNOPHOTO_THUMB_B.jpg 640 # SYNOPHOTO_THUMB_M.jpg 320 # SYNOPHOTO_THUMB_PREVIEW.jpg 160 # SYNOPHOTO_THUMB_S.jpg 120 # SYNOPHOTO_THUMB_XL.jpg 1.280 # # VIDEO # Filename Max width or height (pixels) # SYNOPHOTO:THUMB_M.jpg 320 # SYNOPHOTO:THUMB_XL.jpg video original # SYNOPHOTO:VIDEO_SCREENSHOT.jpg video original # # The short dimension of the thumbnail is calculated with the aspect ratio of the original photo or video. If the video is rotated (metadata Rotation=xx), for instance by using an iPhone, the thumbnails are also rotated and displayed as expected. Metadata are not saved to the thumbnails. # The cover pictures for an album are located in the @eaDir folder at the same level as the album folder. Inside this folder are subfolders with the same album names, containing a file SYNOPHOTO:ALBUM.cover. It’s a text file with the filename of the cover photo, nothing else. If no cover photo is defined, the first image in the album is used as default cover. If a movie is selected as a cover image, the filename of the video is listed in the SYNOPHOTO:ALBUM.cover text file. #A second file SYNOPHOTO:ALBUM.sort is in the same @eaDir folder. A content example is shown below : # #{"type":"3","order":"0","list":["IMG0001.jpg","IMG0002.jpg","IMG0003.jpg"]} #### To Add #root 21846 1 4 Nov08 ? 13:57:52 /var/packages/SynoFinder/target/sbin/synoelasticd #root 21864 1 0 Nov08 ? 00:11:29 /var/packages/SynoFinder/target/sbin/fileindexd conv_progress_photo=/var/spool/conv_progress_photo conv_progress_video=/var/spool/conv_progress_video indexingqueue=/var/spool/syno_indexing_queue WaitTime=5 CPUcores=$(grep -c ^processor /proc/cpuinfo) COLOR_WHITE="\033[01;39m" COLOR_RES="\033[0m" Arguments=() while [[ $# -gt 0 ]] do key="$1" case $key in -w|-wait|--wait) shift WaitTime="$1" shift ;; -h|--help) echo "Usage: niceindexstatus [option]" echo "" echo "Purpose: Provide an overview about the indexing status." echo "Attention: This script has to be executed as root." echo "" echo "Options:" echo "-w|--wait Set the wait time in seconds, default= 5s" echo exit ;; *) # unknown option Arguments+=("$1") # save it in an array for later shift # past argument ;; esac done set -- "${Arguments[@]}" # restore positional parameters # if there is no list of files, then create '.' list file #files=("$@") #nroffiles=${#files[*]} #c="1" #if [ "$nroffiles" -eq "0" ] ; then # for entry in . # do # files[$((c-1))]="$entry" # ((c++)) # done #fi if [[ $EUID -ne 0 ]]; then echo "This script needs to be run as root" exit 1 fi ############################################################ clear # function doesn't seem to work #function procgrep param { # cat param | egrep -v '\/dev\/null|socket:|anon_inode:\[eventpoll\]|total 0|ls: cannot access \/proc\/' | cut -d\> -f2- #} echo -e "${COLOR_WHITE}DATABASE STATUS$COLOR_RES on ($(date '+%Y-%m-%d %H:%M:%S'))" psql mediaserver postgres -c "SELECT 'Music' AS Media, Nr.Count, Path AS LastProcessed FROM music, (SELECT COUNT(*) AS Count FROM music) AS Nr WHERE id=(SELECT MAX(id) FROM music) UNION ALL SELECT 'Photos' AS Media, Nr.Count, Path AS LastProcessed FROM photo, (SELECT COUNT(*) AS Count FROM photo) AS Nr WHERE id=(SELECT MAX(id) FROM photo) UNION all SELECT 'Videos' as Media, Nr.Count, Path AS LastProcessed FROM video, (SELECT COUNT(*) as Count FROM video) as Nr WHERE id=(SELECT MAX(id) FROM video) UNION all SELECT 'Directories' as Media, Nr.Count, Path AS LastProcessed FROM directory, (SELECT COUNT(*) as Count FROM directory) AS Nr WHERE id=(SELECT MAX(id) FROM directory);" |\ egrep -v '^$| rows)|-------------' psql mediaserver postgres -c "SELECT 'Music' AS Media, Date, MDate FROM music, (SELECT COUNT(*) AS Count FROM music) AS Nr WHERE id=(SELECT MAX(id) FROM music) UNION ALL SELECT 'Photos' AS Media, Date, MDate FROM photo, (SELECT COUNT(*) AS Count FROM photo) AS Nr WHERE id=(SELECT MAX(id) FROM photo) UNION all SELECT 'Videos' as Media, Date, MDate FROM video, (SELECT COUNT(*) as Count FROM video) as Nr WHERE id=(SELECT MAX(id) FROM video) UNION all SELECT 'Directories' as Media, Date, MDate FROM directory, (SELECT COUNT(*) as Count FROM directory) AS Nr WHERE id=(SELECT MAX(id) FROM directory);" | egrep -v ' rows)|-------------' echo "Showing real time file access of indexing/thumbnailing processes ($WaitTime sec interval, so some lines are missed):" echo -e "\033[s" # save the cursor position while true; do # echo -e "No open files of indexing/thumnail processes found\033[u" echo -e "${COLOR_WHITE}QUEUE STATUS$COLOR_RES\033[K" if [ -f "$indexingqueue" ] ; then total=$(cat "$indexingqueue" | wc -l) else total="0" fi echo -e "Indexing queue $total \033[K" comp=$(cat "$conv_progress_photo"|grep 'completed='|cut -f2 -d"=") total=$(cat "$conv_progress_photo"|grep 'total='|cut -f2 -d"=") if [ "$total" != "0" ]; then perc=" ($(awk -v comp=$comp -v total=$total 'BEGIN{printf("%.0lf", comp/total*100)}')%)" else perc="" fi echo -en "Photo conversion progress: $comp/$total$perc" comp=$(cat "$conv_progress_photo"|grep 'completed_thumb='|cut -f2 -d"=") total=$(cat "$conv_progress_photo"|grep 'total_thumb='|cut -f2 -d"=") if [ "$total" != "0" ]; then perc="($(awk -v comp=$comp -v total=$total 'BEGIN{printf("%.0lf", comp/total*100)}')%)" else perc="" fi echo -e ", thumbnails: $comp/$total $perc\033[K" comp=$(cat "$conv_progress_video"|grep 'completed='|cut -f2 -d"=") total=$(cat "$conv_progress_video"|grep 'total='|cut -f2 -d"=") if [ "$total" != "0" ]; then perc="($(awk -v comp=$comp -v total=$total 'BEGIN{printf("%.0lf", comp/total*100)}')%)" else perc="" fi echo -e "Video conversion progress: $comp/$total $perc\033[K" echo -en "\033[K" echo -e "${COLOR_WHITE}CURRENT PROCESSES$COLOR_RES\033[K" # database queries postgresphoto=$(ps -ef 2>/dev/null | grep 'postgres photo \[local\]' | grep -v grep | awk '{print $12}'|sort -r|head -n 1) if [ "$cpu_facerecognition" == "%CPU" ]; then cpu_facerecognition="" # the process was already killed fi if [ "$postgresphoto" != "" ]; then cpu_postgresphoto=$(echo "$(top -b -p $(ps -ef 2>/dev/null | grep 'postgres photo \[local\]' | grep -v grep | awk '{print $2}'|sort -r|head -n 1) -n 1 | tail -n 1 | awk -v cpus=$CPUcores '{printf("%2.f\n", $7/cpus)}')") echo -e "postgresphoto $cpu_postgresphoto \t$postgresphoto\033[K" else echo -e "postgresphoto \033[K" fi # synoindexplugind - checks if there is something changed I guess synoindexplugind=$(ps -ef 2>/dev/null| grep synoindexplugind | grep -v grep | awk '{print $2}') if [ "$synoindexplugind" != "" ]; then cpu_synoindexplugind=$(echo "$(top -b -p $(ps -ef 2>/dev/null| grep synoindexplugind | grep -v grep | awk '{print $2}') -n 1 | tail -n 1 | awk -v cpus=$CPUcores '{printf("%2.f\n", $7/cpus)}')") echo -e "synoindexplugind $cpu_synoindexplugind \033[K" else echo -e "synoindexplugind \033[K" fi # mediaparcer (not sure what it does) # if procopenfiles synomediaparser -q; then mediaparser=$(procopenfiles synomediaparser) if [ "$mediaparser" != "" ]; then cpu_mediaparser=$(echo "$(top -b -p $(ps -ef 2>/dev/null| grep synomediaparser | grep -v grep | awk '{print $2}') -n 1 | tail -n 1 | awk -v cpus=$CPUcores '{printf("%2.f\n", $7/cpus)}')") echo -e "mediaparser $cpu_mediaparser \t$synomediaparser \033[K" else echo -e "mediaparser \033[K" fi # fi # indexers synoindexd=$(procopenfiles synoindexd) if [ "$synoindexd" != "" ]; then cpu_synoindexd=$(echo "$(top -b -p $(ps -ef 2>/dev/null| grep synoindexd | grep -v grep | awk '{print $2}') -n 1 | tail -n 1 | awk -v cpus=$CPUcores '{printf("%2.f\n", $7/cpus)}')") echo -e "synoindexd $cpu_synoindexd \t$synoindexd \033[K" else echo -e "synoindexd \033[K" fi # cpu_indexdworkerd="XXXX" # echo -e "\033[01;39m[indexdworkerd]\033[0m $cpu_indexdworkerd\t$(procopenfiles synoindexworkerd) \033[K" # Thumbnails # echo -e "\033[01;39m[synothumb]\033[0m " $(procopenfiles synothumb) \033[K" pid=$(ps -ef | grep synothumb | grep -v grep | awk '{print $2}') if [ "$pid" != "" ]; then synothumb=$(procopenfiles synothumb) cpu_synothumb=$(echo "$(top -b -p $pid -n 1 2>/dev/null| tail -n 1 | awk -v cpus=$CPUcores '{printf("%2.f\n", $7/cpus)}')") echo -e "synothumb $cpu_synothumb \t$synothumb \033[K" lastsynothumb="$synothumb" else echo -e "synothumb \033[K" fi synomkthumbd=$(procopenfiles synomkthumbd) if [ "$synomkthumbd" != "" ]; then cpu_synomkthumbd=" " echo -e "synomkthumbd $cpu_synomkthumbd \t$(procopenfiles synomkthumbd) \033[K" if [[ ${synomkthumbd} != *"/var/spool/"* ]]; then lastsynomkthumbd="$synomkthumbd" fi else echo -e "synomkthumbd \033[K" fi pid=$(ps -ef | grep ffmpeg-thumb | grep -v grep | awk '{print $2}') # echo "*** pid: '$pid'" if [ "$pid" != "" ]; then ffmpegthumb=$(procopenfiles ffmpeg-thumb) cpu_ffmpegthumb=$(echo "$(top -b -p $pid -n 1 2>/dev/null| tail -n 1 | awk -v cpus=$CPUcores '{printf("%2.f\n", $7/cpus)}')") echo -e "ffmpeg-thumb $cpu_ffmpegthumb \t$ffmpegthumb \033[K" lastffmpegthumb="$ffmpegthumb" else echo -e "ffmpeg-thumb \033[K" fi # Others # if [ "$(ps -ef | grep facerecognition | grep -v grep | sed 's/^.* -F //')" != "" ]; then ### echo -e "*** Starting facerecognition part \033[K" string=$(ps -ef | grep facerecognition | grep -v grep) pid=$(echo $string | awk '{print $2}') # get the file facerecognition is working on: facerecognition=$(echo $string | sed 's/^.* -F //') ### echo "*** pid: '$pid', facerec: '$facerecognition'" if [ "$facerecognition" != "" ]; then cpu_facerecognition=$(top -b -p $pid -n 1 | tail -n 1 | awk '{print $7}') if [ "$cpu_facerecognition" == "%CPU" ]; then cpu_facerecognition="" # the process was already killed fi ### echo -e "*** cpu_facerecognition: $cpu_facerecognition\033[K" if [ "$cpu_facerecognition" != "" ]; then # cpu_facerecognition=$(echo "print round($(echo $cpu_facerecognition) / 4,1)" | python 2>/dev/nul) cpu_facerecognition=$(gawk -v var=$cpu_facerecognition -v cpus=$CPUcores 'BEGIN {printf("%2.f", var/cpus)}') else cpu_facerecognition=" ? " fi echo -e "frecognition $cpu_facerecognition \t$facerecognition \033[K" lastfacerecognition="$facerecognition" else echo -e "frecognition \033[K" fi pid=$(ps -ef | grep fileindexd | grep -v grep | awk '{print $2}') if [ "$pid" != "" ]; then if [ -f "/var/log/fileindexd.log" ]; then fileindexd=$(tail -10 /var/log/fileindexd.log | grep 'IndexAttr: ' | tail -1 | cut -d\ -f6-) else # The /var/log/fileindexd.log file does not exist, so we can't provide any details fileindexd="no details as /var/log/fileindexd.log does not exist" fi cpu_fileindexd=$(echo "$(top -b -p $pid -n 1 2>/dev/null| tail -n 1 | awk -v cpus=$CPUcores '{printf("%2.f\n", $7/cpus)}')") echo -e "UniversalSearch/fileindexd $cpu_fileindexd \t$fileindexd \033[K" lastfileindexd="$fileindexd" else echo -e "UniversalSearch/fileindexd \033[K" fi pid=$(ps -ef | grep synoelasticd | grep -v grep | awk '{print $2}') if [ "$pid" != "" ]; then if [ -f "/var/log/fileindexd.log" ]; then # following line needs to be tested/confirmed that it's working: synoelasticd=$(tail -10 /var/log/fileindexd.log | grep 'IndexAttr: ' | tail -1 | cut -d\ -f6-) else synoelasticd="no details as /var/log/fileindexd.log does not exist" fi cpu_synoelasticd=$(echo "$(top -b -p $pid -n 1 2>/dev/null| tail -n 1 | awk -v cpus=$CPUcores '{printf("%2.f\n", $7/cpus)}')") echo -e "UniversalSearch/synoelasticd $cpu_synoelasticd \033[K" #lastfileindexd="$fileindexd" else echo -e "UniversalSearch/synoelasticd \033[K" fi #echo -e "\e[01;39m[spoolfiles]\e[0m photo: $(ls -l /var/spool/conv_progress_photo* | wc -l), video: $(ls -l /var/spool/conv_progress_video* | wc -l) \e[K" echo -en "\033[K" echo -e "${COLOR_WHITE}LAST DETECTED$COLOR_RES\033[K" echo -e "mediaparser ${synomediaparser}NOTimplemented\033[K" echo -e "synoindexd ${synoindexd}NOTimplemented\033[K" echo -e "indexworkerd ${synoindexworkerd}NOTimplemented\033[K" echo -e "synothumb $lastsynothumb \033[K" echo -e "synomkthumbd $lastsynomkthumbd \033[K" echo -e "ffmpegthumb $lastffmpegthumb \033[K" echo -e "facerecognition $lastfacerecognition \033[K" echo -e "fileindexd $lastfileindexd \033[K" echo -e "\033[K\033[1B\033[K\033[1B\033[K\033[1B\033[K\033[1B\033[K\033[1B\033[K" #move cursor down 1 line and clear until end of line and do that a few times echo -e "\033[u" # move cursor to stored position sleep $WaitTime done