Regarding handling of zero, why not try something like:
gen lny=ln(y+1)
reg lny x
You may get negative prediction of y, but you could censored those cases to be zero.
Also, since log(0)= -inf, one may consider such cases as censored, and thus tobit model:
gen lny=ln(y)
quietly sum lny
local newmin=r(min)-1
replace lny=`newmin'
tobit lny x, ll(`newmin')
Above, newmin=r(min)-1, is used just to create a value lower than the r(min), and the actual value does not matter since they would be censored.